db = $db; $this->navEntites(); $this->init(); } public function init() { global $conf, $langs, $mysoc; $files = [ 'Config.php', 'BaseRequestXml.php', 'ManageInvoiceRequestXml.php', 'XmlUtil.php', 'Util.php', 'BaseRequestXml.php', 'TokenExchangeRequestXml.php', 'XsdValidationError.php', 'Xsd.php', 'InvoiceOperations.php', 'Connector.php', 'RequestIdGeneratorInterface.php', 'RequestIdGeneratorBasic.php', 'Reporter.php', 'BaseExceptionResponse.php', 'GeneralErrorResponse.php' ]; foreach ($files as $k => $v) { require_once DOL_DOCUMENT_ROOT . '/custom/nav/lib/NavOnlineInvoice/' . $v; } // $vatID = explode("-",$conf->global->MAIN_INFO_TVAINTRA); $envDEF = [ // 'NAV_USER' => 'xrybkjhakidbl5a', // 'NAV_PASS' => 'eZPDV9Jx6biQHfi', // 'NAV_VAT_NUMBER' => '26646970', // 'NAV_VAT_CODE' => '2', // 'NAV_VAT_COUNTYCODE' => '13', // 'NAV_SIGN_KEY' => '34-b7c5-8f436e541dc33ZQFSD2GZI0E', // 'NAV_EXCHANGE_KEY' => '5b603ZQFSD2G1W1N', // 'NAV_USER' => 'xrybkjhakidbl5a', // 'NAV_PASS' => 'eZPDV9Jx6biQHfi!!+', // 'NAV_VAT_NUMBER' => (isset($vatID[0]))?$vatID[0]:'', // 'NAV_VAT_CODE' => (isset($vatID[1]))?$vatID[1]:'', // 'NAV_VAT_COUNTYCODE' => (isset($vatID[2]))?$vatID[2]:'', // 'NAV_SIGN_KEY' => '34-b7c5-8f436e541dc33ZQFSD2GZI0E', // 'NAV_EXCHANGE_KEY' => '5b603ZQFSD2G1W1N', // 'NAV_SOFTWARE_ID' => 'Dolibarr-NAV-v0.01', 'NAV_SOFTWARE_ID' => 'DOLIBARR-NAV-V0001', 'NAV_SOFTWARE_NAME' => 'Dolibarr', 'NAV_SOFTWARE_OPERATION' => 'ONLINE_SERVICE', 'NAV_SOFTWARE_MAIN_VERSION' => 'v16.0.1', //$conf->global->MAIN_VERSION_LAST_UPGRADE 'NAV_SOFTWARE_DEVELOPER_CONTACT' => 'dolibarr.hu', 'NAV_SOFTWARE_DEVELOPER_NAME' => '-', 'NAV_SOFTWARE_DEVELOPER_COUNTRY_CODE' => 'HU', 'NAV_SOFTWARE_DEVELOPER_TAX_NUMBER' => '-', //'NAV_URL' => "https://api-test.onlineszamla.nav.gov.hu/invoiceService/v3", // teszt // 'NAV_URL' => "https://api.onlineszamla.nav.gov.hu/invoiceService/v3", // éles ]; //!!! // $vat = explode("-",$mysoc->tva_intra); // $_ENV['NAV_VAT_NUMBER'] = $vat[0]; // $_ENV['NAV_VAT_CODE'] = $vat[1]; // $_ENV['NAV_VAT_COUNTYCODE'] = $vat[2]; foreach ($envDEF as $k => $v) { if (isset($conf->global) && isset($conf->global->$k)) { $_ENV[$k] = $conf->global->$k; } else { $_ENV[$k] = (isset($_ENV[$k])) ? $_ENV[$k] : $v; } } // $this->userData = array( // "login" => $_ENV['NAV_USER'], // "password" => $_ENV['NAV_PASS'], // //"passwordHash" => "...", // Opcionális, a jelszó már SHA512 hashelt változata. Amennyiben létezik ez a változó, akkor az authentikáció során ezt használja // "taxNumber" => $_ENV['NAV_VAT_NUMBER'], //"12345678", // "signKey" => $_ENV['NAV_SIGN_KEY'], //"sign-key", // "exchangeKey" => $_ENV['NAV_EXCHANGE_KEY'], // "exchange-key", // ); $this->softwareData = array( "softwareId" => "" . $_ENV['NAV_SOFTWARE_ID'], "softwareName" => $_ENV['NAV_SOFTWARE_NAME'], "softwareOperation" => $_ENV['NAV_SOFTWARE_OPERATION'], //"ONLINE_SERVICE", "softwareMainVersion" => $_ENV['NAV_SOFTWARE_MAIN_VERSION'], //"string", "softwareDevName" => $_ENV['NAV_SOFTWARE_DEVELOPER_NAME'], //"string", "softwareDevContact" => $_ENV['NAV_SOFTWARE_DEVELOPER_CONTACT'], //"string", "softwareDevCountryCode" => $_ENV['NAV_SOFTWARE_DEVELOPER_COUNTRY_CODE'], //"HU", "softwareDevTaxNumber" => $_ENV['NAV_SOFTWARE_DEVELOPER_TAX_NUMBER'], //"string", ); foreach ($this->navEntity as $k => $v) { $this->apiUrl = $v['NAV_URL']; if (strpos($this->apiUrl, "api-test") !== false) { $this->userData = array( "login" => 'xrybkjhakidbl5a', //UMS technikai felhasználó teszthez "password" => 'eZPDV9Jx6biQHfi!!+', //UMS technikai felhasználó teszthez "taxNumber" => '26646970', //UMS technikai felhasználó teszthez "signKey" => '34-b7c5-8f436e541dc33ZQFSD2GZI0E', //UMS technikai felhasználó teszthez "exchangeKey" => '5b603ZQFSD2G1W1N', //UMS technikai felhasználó teszthez ); } else { $this->userData = array( "login" => $v['NAV_USER'], "password" => $v['NAV_PASS'], //"passwordHash" => "...", // Opcionális, a jelszó már SHA512 hashelt változata. Amennyiben létezik ez a változó, akkor az authentikáció során ezt használja "taxNumber" => $v['NAV_VAT_NUMBER'], //"12345678", "signKey" => $v['NAV_SIGN_KEY'], //"sign-key", "exchangeKey" => $v['NAV_EXCHANGE_KEY'], // "exchange-key", ); } $config = new NavOnlineInvoice\Config($this->apiUrl, $this->userData, $this->softwareData); $config->setCurlTimeout(70); // 70 másodperces cURL timeout (NAV szerver hívásnál), opcionális $this->NavReporter[$k] = new NavOnlineInvoice\Reporter($config); } // "Connection error. CURL error code: 60" hiba esetén add hozzá a következő sort: // $config->verifySSL = false; } public function invoiceXML($invoice) { //print_r($invoice);exit; global $conf, $langs; $xmlstr = ''; $xmlstr .= ''; $xmlstr .= ''; $xml = new SimpleXMLElement($xmlstr); // $ns = $xml->getNamespaces(true); // print_r($ns);exit; // $xml->addAttribute('invoiceNumber',$invoice->newref); if (!isset($invoice->newref) || !$invoice->newref) { $xml->addChild('invoiceNumber', $invoice->ref); } else { $xml->addChild('invoiceNumber', $invoice->newref); } // $xml->addChild('invoiceIssueDate',date("Y-m-d",$invoice->date_modification)); $xml->addChild('invoiceIssueDate', date("Y-m-d")); $xml->addChild('completenessIndicator', 'false'); $invoiceMain = $xml->addChild('invoiceMain'); // $invoiceMain->addAttribute('',$invoice[]); $invoiceXml = $invoiceMain->addChild('invoice'); if ($invoice->fk_facture_source != '' && $invoice->type == 2) { $invoiceReference = $invoiceXml->addChild('invoiceReference'); $invoiceReference->addChild('originalInvoiceNumber', $this->getSourceRef($invoice->fk_facture_source)); $invoiceReference->addChild('modifyWithoutMaster', 'false'); $invoiceReference->addChild('modificationIndex', 1); } // $invoice->addAttribute('',$invoice[]); $invoiceHead = $invoiceXml->addChild('invoiceHead'); $supplierInfo = $invoiceHead->addChild('supplierInfo'); $supplierInfo->addChild('supplierTaxNumber'); //$supplierInfo->supplierTaxNumber[0]->addChild('base:taxpayerId',$_ENV['NAV_VAT_NUMBER'],"http://schemas.nav.gov.hu/OSA/3.0/base"); //$supplierInfo->supplierTaxNumber[0]->addChild('base:vatCode',$_ENV['NAV_VAT_CODE'],"http://schemas.nav.gov.hu/OSA/3.0/base"); //$supplierInfo->supplierTaxNumber[0]->addChild('base:countyCode',$_ENV['NAV_VAT_COUNTYCODE'],"http://schemas.nav.gov.hu/OSA/3.0/base"); $supplierInfo->supplierTaxNumber[0]->addChild('base:taxpayerId', $this->navEntity['e_' . $invoice->entity]['NAV_VAT_NUMBER'], "http://schemas.nav.gov.hu/OSA/3.0/base"); $supplierInfo->supplierTaxNumber[0]->addChild('base:vatCode', $this->navEntity['e_' . $invoice->entity]['NAV_VAT_CODE'], "http://schemas.nav.gov.hu/OSA/3.0/base"); $supplierInfo->supplierTaxNumber[0]->addChild('base:countyCode', $this->navEntity['e_' . $invoice->entity]['NAV_VAT_COUNTYCODE'], "http://schemas.nav.gov.hu/OSA/3.0/base"); $supplierInfo->addChild('supplierName', $this->navEntity['e_' . $invoice->entity]['MAIN_INFO_SOCIETE_NOM']); $supplierInfo->addChild('supplierAddress'); $simpleAddress = $supplierInfo->supplierAddress[0]->addChild('base:simpleAddress', null, "http://schemas.nav.gov.hu/OSA/3.0/base"); $simpleAddress->addChild('base:countryCode', 'HU', "http://schemas.nav.gov.hu/OSA/3.0/base"); $simpleAddress->addChild('base:postalCode', $this->navEntity['e_' . $invoice->entity]['MAIN_INFO_SOCIETE_ZIP'], "http://schemas.nav.gov.hu/OSA/3.0/base"); $simpleAddress->addChild('base:city', $this->navEntity['e_' . $invoice->entity]['MAIN_INFO_SOCIETE_TOWN'], "http://schemas.nav.gov.hu/OSA/3.0/base"); $simpleAddress->addChild('base:additionalAddressDetail', $this->navEntity['e_' . $invoice->entity]['MAIN_INFO_SOCIETE_ADDRESS'], "http://schemas.nav.gov.hu/OSA/3.0/base"); $customerInfo = $invoiceHead->addChild('customerInfo'); $customerInfo->addChild('customerVatStatus', 'DOMESTIC'); //... !!! $customerInfo->addChild('customerVatData'); $customerInfo->customerVatData[0]->addChild('customerTaxNumber'); $customerInfo->customerVatData[0]->customerTaxNumber[0]->addChild('base:taxpayerId', '12345678', "http://schemas.nav.gov.hu/OSA/3.0/base"); // $customerInfo->customerVatData[0]->customerTaxNumber[0]->addChild('base:taxpayerId',$invoice->thirdparty->,"http://schemas.nav.gov.hu/OSA/3.0/base"); $customerInfo->addChild('customerName', $invoice->thirdparty->name); $customerInfo->addChild('customerAddress'); $simpleAddress2 = $customerInfo->customerAddress[0]->addChild('base:simpleAddress', null, "http://schemas.nav.gov.hu/OSA/3.0/base"); $simpleAddress2->addChild('base:countryCode', $invoice->thirdparty->country_code, "http://schemas.nav.gov.hu/OSA/3.0/base"); $simpleAddress2->addChild('base:postalCode', $invoice->thirdparty->zip, "http://schemas.nav.gov.hu/OSA/3.0/base"); $simpleAddress2->addChild('base:city', $invoice->thirdparty->town, "http://schemas.nav.gov.hu/OSA/3.0/base"); $simpleAddress2->addChild('base:additionalAddressDetail', $invoice->thirdparty->address, "http://schemas.nav.gov.hu/OSA/3.0/base"); $invoiceDetail = $invoiceHead->addChild('invoiceDetail'); //...!!! $invoiceDetail->addChild('invoiceCategory', 'NORMAL'); $invoiceDetail->addChild('invoiceDeliveryDate', ($invoice->delivery_date) ? date('Y-m-d', $invoice->delivery_date) : date('Y-m-d')); $invoiceDetail->addChild('currencyCode', $invoice->multicurrency_code); $multicurrency_tx = $invoice->multicurrency_code == 'HUF' ? '1' : number_format(1 / $invoice->multicurrency_tx, 6, '.', ''); $invoiceDetail->addChild('exchangeRate', $multicurrency_tx); $paymentMethod = $this->getPaymentMethod($invoice->mode_reglement_code); $invoiceDetail->addChild('paymentMethod', $paymentMethod); $invoiceDetail->addChild('paymentDate', date('Y-m-d', (int)$invoice->date_lim_reglement)); $invoiceDetail->addChild('invoiceAppearance', 'PAPER'); $invoiceLines = $invoiceXml->addChild('invoiceLines'); $invoiceLine = []; $vatrateArray = []; $invoiceLines->addChild('mergedItemIndicator', 'false'); foreach ($invoice->lines as $k => $line) { $invoiceLine[$k] = $invoiceLines->addChild('line'); $invoiceLine[$k]->addChild('lineNumber', $k + 1); if ($invoice->fk_facture_source != '' && $invoice->type == 2) { $lineModificationReference = $invoiceLine[$k]->addChild('lineModificationReference'); $lineModificationReference->addChild('lineNumberReference', $line->rowid); $lineModificationReference->addChild('lineOperation', 'CREATE'); } $invoiceLine[$k]->addChild('productCodes'); $invoiceLine[$k]->productCodes[0]->addChild('productCode'); $invoiceLine[$k]->productCodes[0]->productCode[0]->addChild('productCodeCategory', 'OWN'); $invoiceLine[$k]->productCodes[0]->productCode[0]->addChild('productCodeValue', '137'); $invoiceLine[$k]->addChild('lineExpressionIndicator', 'true'); $type = 'SERVICE'; // $desc = $line->desc; $desc = ($line->libelle) ? $line->libelle : $desc; if ($line->product_type == 0) { $type = 'PRODUCT'; // $desc = $line->product_label; } if ($desc == '') { $desc = '__'; } $desc = str_replace('&', '&', $desc); // elseif($desc = $line->desc){} $invoiceLine[$k]->addChild('lineNatureIndicator', $type); $invoiceLine[$k]->addChild('lineDescription', $desc); $invoiceLine[$k]->addChild('quantity', $line->qty); $invoiceLine[$k]->addChild('unitOfMeasure', 'PIECE'); $invoiceLine[$k]->addChild('unitPrice', $line->subprice); $invoiceLine[$k]->addChild('unitPriceHUF', $line->total_ht); $invoiceLine[$k]->addChild('lineAmountsNormal'); $invoiceLine[$k]->lineAmountsNormal[0]->addChild('lineNetAmountData'); $invoiceLine[$k]->lineAmountsNormal[0]->lineNetAmountData[0]->addChild('lineNetAmount', round($line->multicurrency_total_ht, 2)); $vatrateArray[number_format($line->tva_tx, 0)]['m_ht'] += $line->multicurrency_total_ht; $invoiceLine[$k]->lineAmountsNormal[0]->lineNetAmountData[0]->addChild('lineNetAmountHUF', round($line->total_ht, 2)); $vatrateArray[number_format($line->tva_tx, 0)]['ht'] += $line->total_ht; $invoiceLine[$k]->lineAmountsNormal[0]->addChild('lineVatRate'); $invoiceLine[$k]->lineAmountsNormal[0]->lineVatRate[0]->addChild('vatPercentage', round((float)$line->tva_tx / 100, 2)); $invoiceLine[$k]->lineAmountsNormal[0]->addChild('lineVatData'); $invoiceLine[$k]->lineAmountsNormal[0]->lineVatData[0]->addChild('lineVatAmount', round($line->multicurrency_total_tva, 2)); $vatrateArray[number_format($line->tva_tx, 0)]['m_tva'] += $line->multicurrency_total_tva; $invoiceLine[$k]->lineAmountsNormal[0]->lineVatData[0]->addChild('lineVatAmountHUF', round($line->total_tva, 2)); $vatrateArray[number_format($line->tva_tx, 0)]['tva'] += $line->total_tva; $invoiceLine[$k]->lineAmountsNormal[0]->addChild('lineGrossAmountData'); $invoiceLine[$k]->lineAmountsNormal[0]->lineGrossAmountData[0]->addChild('lineGrossAmountNormal', round($line->multicurrency_total_ttc, 2)); $invoiceLine[$k]->lineAmountsNormal[0]->lineGrossAmountData[0]->addChild('lineGrossAmountNormalHUF', round($line->total_ttc, 2)); } //print_r($vatrateArray);exit; $invoiceSummary = $invoiceXml->addChild('invoiceSummary'); $summaryNormal = $invoiceSummary->addChild('summaryNormal'); $i = 1; foreach ($vatrateArray as $vatKey => $vatValue) { $percentage = strlen((string) $vatKey) > 1 ? '0.' . $vatKey : '0.0' . $vatKey; ${"summaryByVatRate" . $i} = $summaryNormal->addChild('summaryByVatRate'); ${"vatRate" . $i} = ${"summaryByVatRate" . $i}->addChild('vatRate'); ${"vatRate" . $i}->addChild('vatPercentage', $percentage); ${"vatRateNetData" . $i} = ${"summaryByVatRate" . $i}->addChild('vatRateNetData'); ${"vatRateNetData" . $i}->addChild('vatRateNetAmount', round($vatValue['m_ht'], 2)); ${"vatRateNetData" . $i}->addChild('vatRateNetAmountHUF', round($vatValue['ht'], 2)); ${"vatRateVatData" . $i} = ${"summaryByVatRate" . $i}->addChild('vatRateVatData'); ${"vatRateVatData" . $i}->addChild('vatRateVatAmount', round($vatValue['m_tva'], 2)); ${"vatRateVatData" . $i}->addChild('vatRateVatAmountHUF', round($vatValue['tva'], 2)); ${"vatRateGrossData" . $i} = ${"summaryByVatRate" . $i}->addChild('vatRateGrossData'); ${"vatRateGrossData" . $i}->addChild('vatRateGrossAmount', round($vatValue['m_ht'] + $vatValue['m_tva'], 2)); ${"vatRateGrossData" . $i}->addChild('vatRateGrossAmountHUF', round($vatValue['ht'] + $vatValue['tva'], 2)); $i++; } $summaryNormal->addChild('invoiceNetAmount', round($invoice->multicurrency_total_ht, 2)); $summaryNormal->addChild('invoiceNetAmountHUF', round($invoice->total_ht, 2)); $summaryNormal->addChild('invoiceVatAmount', round($invoice->multicurrency_total_tva, 2)); $summaryNormal->addChild('invoiceVatAmountHUF', round($invoice->total_tva, 2)); $summaryGrossData = $invoiceSummary->addChild('summaryGrossData'); $summaryGrossData->addChild('invoiceGrossAmount', number_format($invoice->multicurrency_total_ttc, 2, '.', '')); $summaryGrossData->addChild('invoiceGrossAmountHUF', number_format($invoice->total_ttc, 2, '.', '')); //print_r($summaryNormal);exit; //echo $xml->asXML();exit; return $xml; } private function getPaymentMethod($paymentMethod) { switch ($paymentMethod) { case "LIQ": return "CASH"; case "CB": return "CARD"; case "VIR": return "TRANSFER"; } } private function getSourceRef($rowid) { global $db; $sql = "SELECT ref FROM llx_facture WHERE rowid = {$rowid}"; $result = $db->query($sql); if (pg_num_rows($result) > 0) { $row = pg_fetch_all($result); return $row[0]['ref']; } } public function test() { try { $token = $this->NavReporter["e_..."]->tokenExchange(); print "Token: " . $token; } catch (Exception $ex) { print get_class($ex) . ": " . $ex->getMessage(); } } public function vat($number) { try { $result = $this->NavReporter["e_1"]->queryTaxpayer($number); if ($result) { print "Az adószám valid.\n"; // print "Az adószámhoz tartozó név: $result->taxpayerName\n"; // print "További lehetséges információk az adózóról:\n"; print_r($result); // print_r($result->taxpayerShortName); // print_r($result->taxNumberDetail); // print_r($result->vatGroupMembership); // print_r($result->taxpayerAddressList); } else { print "Az adószám nem valid."; } } catch (Exception $ex) { print get_class($ex) . ": " . $ex->getMessage(); } } public function syncNAV($limit = 10) { global $user; // if (!DolibarrApiAccess::$user->rights->produit->lire) { // throw new RestException(403); // } // require_once(DOL_DOCUMENT_ROOT.'/custom/nav/class/nav.class.php'); require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; $error = 0; $this->output = ''; $this->error = ''; $transactionIds = []; $object = new Facture($this->db); $extrafields = new ExtraFields($this->db); // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); $sql = "SELECT fe.fk_object,f.type,f.entity FROM " . MAIN_DB_PREFIX . "facture f RIGHT JOIN " . MAIN_DB_PREFIX . "facture_extrafields fe ON f.rowid = fe.fk_object WHERE f.fk_statut = 2 AND type NOT IN(7,8) AND fe.nav_transaction_id IS NULL LIMIT " . (int)$limit . ";"; // echo $sql."\n"; $resql = $this->db->query($sql); if (!empty($resql)) { while ($obj = $this->db->fetch_object($resql)) { if ($object->fetch($obj->fk_object)) { // print_r($object);exit; $object->fetch_thirdparty(); if ($xml = $this->invoiceXML($object)) { try { // Az $invoiceXml tartalmazza a számla (szakmai) SimpleXMLElement objektumot //$invoice->type => // 0 számla // 1 helyesbítő számla // 2 sztornó számla $action = "CREATE"; if ($object->type == 1) { $action = "MODIFY"; } elseif ($object->type == 2) { $action = "STORNO"; } else { } if (isset($this->NavReporter["e_" . $object->entity])) { if ($transactionId = $this->NavReporter["e_" . $object->entity]->manageInvoice($xml, $action)) { // print "Tranzakciós azonosító a státusz lekérdezéshez: " . $transactionId; $sql = 'UPDATE ' . MAIN_DB_PREFIX . "facture_extrafields SET xml='" . $this->db->escape($xml->asXML()) . "', nav_transaction_id='" . $this->db->escape($transactionId) . "' WHERE fk_object = " . $this->db->escape($object->id) . ";"; // echo $sql."\n"; // exit; $resql2 = $this->db->query($sql); if (!$resql2) { //... $error++; $this->error .= json_encode([ "sql" => $sql, "transactionId" => $transactionId, "fk_object" => $object->id ]); } $transactionIds[$transactionId] = $object->id; } } else { $transactionIds["_error"][] = [$object->id, $object->entity]; } } catch (Exception $ex) { $this->error .= get_class($ex) . ": " . $ex->getMessage() . " - entity: " . $object->entity; $error++; return $error; exit; //!!! valamit ki kell találni a tesztelésre! } // sleep(1); // exit; } } } } $this->output = json_encode($transactionIds); return $error; // return [ // "transactionId" => $transactionIds, // "error" => $error // ]; } protected function navEntites() { $this->navEntity = []; $sql = "SELECT name,entity,value FROM " . MAIN_DB_PREFIX . "const WHERE (name IN('MAIN_INFO_SOCIETE_NOM', 'MAIN_INFO_SOCIETE_ADDRESS', 'MAIN_INFO_SOCIETE_TOWN', 'MAIN_INFO_SOCIETE_ZIP') OR name LIKE 'NAV_%');"; //print $sql;exit; $resql = $this->db->query($sql); if (!empty($resql)) { while ($obj = $this->db->fetch_object($resql)) { if (!isset($this->navEntity["e_" . $obj->entity])) { $this->navEntity["e_" . $obj->entity] = []; } $this->navEntity["e_" . $obj->entity][$obj->name] = $obj->value; } } // return $this->navEntity; } }