* Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2008 Raphael Bertrand * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2012 Cédric Salvador * Copyright (C) 2012-2014 Raphaël Doursenaud * Copyright (C) 2015 Marcos García * Copyright (C) 2017-2018 Ferran Marcet * Copyright (C) 2018-2020 Frédéric France * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * or see https://www.gnu.org/ */ /** * \file htdocs/core/modules/facture/doc/pdf_crabe.modules.php * \ingroup facture * \brief File of class to generate customers invoices from crabe model */ require_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php'; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/pdf.lib.php'; dol_include_once('/cfdixml/lib/cfdixml.lib.php'); // dol_include_once('/cfdixml/lib/phpqrcode/qrlib.php'); dol_include_once('/cfdixml/vendor/autoload.php'); class pdf_cfdixmlv3 extends ModelePDFFactures { /** * @var DoliDb Database handler */ public $db; /** * @var string model name */ public $name; /** * @var string model description (short text) */ public $description; /** * @var int Save the name of generated file as the main doc when generating a doc with this template */ public $update_main_doc_field; /** * @var string document type */ public $type; /** * @var array Minimum version of PHP required by module. * e.g.: PHP ≥ 7.0 = array(7, 0) */ public $phpmin = array(7, 0); /** * Dolibarr version of the loaded document * @var string */ public $version = 'dolibarr'; /** * @var int page_largeur */ public $page_largeur; /** * @var int page_hauteur */ public $page_hauteur; /** * @var array format */ public $format; /** * @var int marge_gauche */ public $marge_gauche; /** * @var int marge_droite */ public $marge_droite; /** * @var int marge_haute */ public $marge_haute; /** * @var int marge_basse */ public $marge_basse; /** * Issuer * @var Societe Object that emits */ public $emetteur; /** * @var bool Situation invoice type */ public $situationinvoice; /** * @var float X position for the situation progress column */ public $posxprogress; /** * @var int Category of operation */ public $categoryOfOperation = -1; // unknown by default /** * Constructor * * @param DoliDB $db Database handler */ public function __construct($db) { global $conf, $langs, $mysoc; // Translations $langs->loadLangs(array("main", "bills", "cfdixml@cfdixml")); $this->db = $db; $this->name = "PDF CfdiXMLv3"; $this->description = $langs->trans('PDFCfdiXMLv3'); $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template // Dimension page // $this->type = 'pdf'; // $formatarray = pdf_getFormat(); // $this->page_largeur = $formatarray['width']; // $this->page_hauteur = $formatarray['height']; // $this->format = array($this->page_largeur, $this->page_hauteur); // $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10); // $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10); // $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10); // $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10); // $this->option_logo = 1; // Display logo // $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION // $this->option_modereg = 1; // Display payment mode // $this->option_condreg = 1; // Display payment terms // $this->option_multilang = 1; // Available in several languages // $this->option_escompte = 1; // Displays if there has been a discount // $this->option_credit_note = 1; // Support credit notes // $this->option_freetext = 1; // Support add of a personalised text // $this->option_draft_watermark = 1; // Support add of a watermark on drafts // $this->watermark = ''; // // Get source company // $this->emetteur = $mysoc; // if (empty($this->emetteur->country_code)) { // $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined // } // // Define position of columns // $this->posxdesc = $this->marge_gauche + 1; // if (!empty($conf->global->PRODUCT_USE_UNITS)) { // $this->posxref = 1; // $this->posxumed = 1; // $this->posxclaveprodserv = 1; // $this->posxtva = 101; // $this->posxup = 118; // $this->posxqty = 135; // $this->posxunit = 151; // } else { // $this->posxref = 1; // $this->posxumed = 1; // $this->posxclaveprodserv = 1; // $this->posxtva = 106; // $this->posxup = 122; // $this->posxqty = 145; // $this->posxunit = 162; // } // $this->posxprogress = 151; // Only displayed for situation invoices // $this->posxdiscount = 162; // $this->posxprogress = 174; // $this->postotalht = 174; // if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) || !empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) { // $this->posxtva = $this->posxup; // } // $this->posxpicture = $this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images // if ($this->page_largeur < 210) { // To work with US executive format // $this->posxpicture -= 20; // $this->posxtva -= 20; // $this->posxup -= 20; // $this->posxqty -= 20; // $this->posxunit -= 20; // $this->posxdiscount -= 20; // $this->posxprogress -= 20; // $this->postotalht -= 20; // } // $this->tva = array(); // $this->tva_array = array(); // $this->localtax1 = array(); // $this->localtax2 = array(); // $this->atleastoneratenotnull = 0; // $this->atleastonediscount = 0; // $this->situationinvoice = false; } /** * Function to build pdf onto disk * * @param Facture $object Object to generate * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details * @param int $hidedesc Do not show desc * @param int $hideref Do not show ref * @return int 1=OK, 0=KO */ public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) { global $outputlangs, $user, $langs, $conf, $mysoc, $hookmanager, $nblines; if ($object->specimen) { $dir = empty($conf->facture->multidir_output[$object->entity]) ? $conf->facture->dir_output : $conf->facture->multidir_output[$object->entity]; $file = $dir . "/SPECIMEN.pdf"; } else if (!empty($object->array_options['options_cfdixml_UUID'])) { $objectref = dol_sanitizeFileName($object->ref); $dir = $conf->facture->dir_output . "/" . $objectref; $file = $dir . "/" . $objectref . '_' . $object->array_options['options_cfdixml_UUID'] . ".pdf"; $cfdifile = $dir . "/" . $objectref . '_' . $object->array_options['options_cfdixml_UUID'] . ".xml"; $xml = file_get_contents($cfdifile); // clean cfdi $xml = \PhpCfdi\CfdiCleaner\Cleaner::staticClean($xml); // create the main node structure $comprobante = \CfdiUtils\Nodes\XmlNodeUtils::nodeFromXmlString($xml); // create the CfdiData object, it contains all the required information $cfdiData = (new \PhpCfdi\CfdiToPdf\CfdiDataBuilder()) ->build($comprobante); // create the converter $converter = new \PhpCfdi\CfdiToPdf\Converter( new \PhpCfdi\CfdiToPdf\Builders\Html2PdfBuilder() ); // create the invoice as output.pdf $converter->createPdfAs($cfdiData, $file); } else { $objectref = dol_sanitizeFileName($object->ref); $dir = (empty($conf->facture->multidir_output[$object->entity]) ? $conf->facture->dir_output : $conf->facture->multidir_output[$object->entity]) . "/" . $objectref; $file = $dir . "/" . $objectref . ".pdf"; } if (!file_exists($dir)) { if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } return 1; } protected function _cfdixmldata($xml = null) { $data = array(); if (!empty($xml)) { $xml = base64_decode($xml); } else { $dir = DOL_DOCUMENT_ROOT; if (file_exists(DOL_DOCUMENT_ROOT . '/custom/cfdixml/core/modules/modCfdixml.class.php')) { $dir .= '/custom/cfdixml/resources/cfdv4-example.xml'; } else { $dir .= '/cfdixml/resources/cfdv4-example.xml'; } $xml = file_get_contents($dir); } $cfdi = \CfdiUtils\Cfdi::newFromString($xml); // obtener el QuickReader con el método dedicado $data = $cfdi->getQuickReader(); return $data; } }