| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- <?php
- namespace NavOnlineInvoice;
- use Exception;
- class InvoiceOperations {
- const MAX_INVOICE_COUNT = 100;
- const COMPRESSION_LEVEL = 1;
- protected $invoices;
- protected $compression;
- /**
- * Az automatikusan felismert technicalAnnulment értéke az első hozzáadott számla alapján.
- * `null` esetén még nincs számla hozzáadva
- *
- * @var bool|null
- */
- protected $detectedTechnicalAnnulment = null;
- protected $index;
- protected $schemaValidation = true;
- /**
- * Számlákat (számla műveleteket) összefogó objektum (collection) készítése
- *
- * @param boolean $compression gzip tömörítés alkalmazása, részletek: NAV dokumentáció, 1.6.5 Tömörítés és méretkorlát
- */
- function __construct($compression = false) {
- $this->invoices = array();
- $this->index = 1;
- $this->compression = $compression;
- }
- /**
- * Számla hozzáadásakor ellenőrizze az XML adatot a DATA sémával szemben
- *
- * @param boolean $flag
- */
- public function useDataSchemaValidation($flag = true) {
- $this->schemaValidation = $flag;
- }
- /**
- * Számla ('szakmai XML') hozzáadása
- *
- * @param \SimpleXMLElement $xml Számla adatai (szakmai XML)
- * @param string [$operation = "CREATE"] Számlaművelet Enum(CREATE, MODIFY, STORNO, ANNUL)
- * @param string [$electronicInvoiceHash = null] Számla SHA3-512 hash értéke elektronikus számla esetén. Ha completenessIndicator=true, akkor itt null-t kell átadni.
- * @return int A beszúrt művelet sorszáma (index)
- * @throws \Exception
- */
- public function add(\SimpleXMLElement $xml, $operation = "CREATE", $electronicInvoiceHash = null) {
- // XSD validálás
- if ($this->schemaValidation) {
- $xsdFile = $operation === "ANNUL" ? Config::getAnnulmentXsdFilename() : Config::getDataXsdFilename();
- Xsd::validate($xml->asXML(), $xsdFile);
- }
- // Számlák maximum számának ellenőrzése
- if (count($this->invoices) > self::MAX_INVOICE_COUNT) {
- throw new Exception("Maximum " . self::MAX_INVOICE_COUNT . " számlát lehet egyszerre elküldeni!");
- }
- // Technical annulment flag beállítása és ellenőrzése
- $this->detectTechnicalAnnulment($operation);
- $completenessIndicator = $this->isComplete($xml);
- if ($completenessIndicator and $electronicInvoiceHash) {
- throw new Exception("completenessIndicator=true esetén az electronicInvoiceHash értékét a nav-online-invoice modul számolja automatikusan, így ezt a paramétert üresen kell hagyni!");
- }
- $invoiceBase64Data = $this->convertXml($xml);
- if ($completenessIndicator) {
- $electronicInvoiceHash = Util::sha3_512($invoiceBase64Data);
- }
- $idx = $this->index;
- $this->index++;
- $this->invoices[] = array(
- "index" => $idx,
- "operation" => $operation,
- "invoice" => $invoiceBase64Data,
- "electronicInvoiceHash" => $electronicInvoiceHash,
- );
- return $idx;
- }
- /**
- * A felismert technicalAnnulment értékének lekérdezése.
- * Ha még nem adtunk hozzá számlát, akkor hibát fog dobni.
- *
- * @return bool technicalAnnulment
- * @throws Exception
- */
- public function isTechnicalAnnulment() {
- if (!$this->invoices) {
- throw new Exception("Még nincs számla hozzáadva, így a technicalAnnulment értéke nem megállapítható!");
- }
- return $this->detectedTechnicalAnnulment;
- }
- protected function detectTechnicalAnnulment($operation) {
- $currentFlag = ($operation === 'ANNUL');
- // Ha még nincs beállítva, akkor beállítjuk
- if (is_null($this->detectedTechnicalAnnulment)) {
- $this->detectedTechnicalAnnulment = $currentFlag;
- }
- // Ha a korábban beállított nem egyezik az aktuálissal, akkor hiba dobása (NAV nem fogadja el)
- if ($this->detectedTechnicalAnnulment !== $currentFlag) {
- throw new Exception("Az egyszerre feladott számlák nem tartalmazhatnak vegyesen ANNUL, illetve ettől eltérő operation értéket!");
- }
- }
- public function getInvoices() {
- return $this->invoices;
- }
- /**
- * Utoljára hozzáadott számla electronicInvoiceHash értékét adja vissza.
- * Ez lehet paraméterben átadott, vagy completenessIndicator=true esetén a modul által számolt hash.
- *
- * @return string
- */
- public function getLastInvoiceHash() {
- if (!$this->invoices) {
- return null;
- }
- $lastInvoice = $this->invoices[count($this->invoices) - 1];
- return $lastInvoice['electronicInvoiceHash'];
- }
- public function isCompressed() {
- return $this->compression;
- }
- /**
- * XML objektum konvertálása base64-es szöveggé
- * @param \SimpleXMLElement $xml
- * @return string
- */
- protected function convertXml(\SimpleXMLElement $xml) {
- $xml = $xml->asXML();
- if ($this->compression) {
- $xml = gzencode($xml, self::COMPRESSION_LEVEL);
- }
- return base64_encode($xml);
- }
- protected function isComplete(\SimpleXMLElement $xml) {
- return (string)$xml->completenessIndicator === 'true';
- }
- /**
- * Egy darab számla XML-t átadva visszaad egy InvoiceOperations példányt,
- * amit a Reporter::manageInvoice metódusa fogad paraméterben
- *
- * @param \SimpleXMLElement $xml
- * @param string $operation
- * @param boolean $compression gzip tömörítés alkalmazása, részletek: NAV dokumentáció, 1.6.5 Tömörítés és méretkorlát
- * @return InvoiceOperations
- */
- public static function convertFromXml($xml, $operation, $compression = false) {
- $invoiceOperations = new self($compression);
- $invoiceOperations->useDataSchemaValidation();
- $invoiceOperations->add($xml, $operation);
- return $invoiceOperations;
- }
- /**
- * Számla dekódolása (base64 és opcionálisan gzip)
- *
- * @param string $base64data
- * @param boolean $isCompressed
- * @return \SimpleXMLElement
- */
- public static function convertToXml($base64data, $isCompressed = false) {
- $isCompressed = ($isCompressed === true or (string)$isCompressed === 'true');
- $data = base64_decode($base64data);
- if ($isCompressed) {
- $data = gzdecode($data);
- }
- return simplexml_load_string($data);
- }
- }
|