dolibarr  19.0.0-dev
modules_facture.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
5  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
6  * Copyright (C) 2014 Marcos GarcĂ­a <marcosgdf@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  * or see https://www.gnu.org/
21  */
22 
30 require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Required because used in classes that inherit
33 
34 // For the experimental feature using swiss QR invoice generated by composer lib sparin/swiss-qr-bill
35 use Sprain\SwissQrBill;
36 
40 abstract class ModelePDFFactures extends CommonDocGenerator
41 {
45  public $error = '';
46 
47  public $posxpicture;
48  public $posxtva;
49  public $posxup;
50  public $posxqty;
51  public $posxunit;
52  public $posxdesc;
53  public $posxdiscount;
54  public $postotalht;
55 
56  public $tva;
57  public $tva_array;
58  public $localtax1;
59  public $localtax2;
60 
61  public $atleastonediscount = 0;
62  public $atleastoneratenotnull = 0;
63 
64  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
72  public static function liste_modeles($db, $maxfilenamelength = 0)
73  {
74  // phpcs:enable
75  $type = 'invoice';
76  $list = array();
77 
78  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
79  $list = getListOfModels($db, $type, $maxfilenamelength);
80 
81  return $list;
82  }
83 
91  private function getSwissQrBill(Facture $object, Translate $langs)
92  {
93  global $conf;
94 
95  if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') != 'bottom') {
96  return false;
97  }
98 
99  if ($object->mode_reglement_code != 'VIR') {
100  $this->error = $langs->transnoentities("SwissQrOnlyVIR");
101  return false;
102  }
103 
104  if (empty($object->fk_account)) {
105  $this->error = 'Bank account must be defined to use this experimental feature';
106  return false;
107  }
108 
109  // Load the autoload file generated by composer
110  if (file_exists(DOL_DOCUMENT_ROOT.'/includes/sprain/swiss-qr-bill/autoload.php')) {
111  require_once DOL_DOCUMENT_ROOT.'/includes/sprain/swiss-qr-bill/autoload.php';
112  } elseif (file_exists(DOL_DOCUMENT_ROOT.'/includes/autoload.php')) {
113  require_once DOL_DOCUMENT_ROOT.'/includes/autoload.php';
114  } else {
115  $this->error = 'PHP library sprain/swiss-qr-bill was not found. Please install it with:<br>cd '.dirname(DOL_DOCUMENT_ROOT).'; cp composer.json.disabled composer.json; composer require sprain/swiss-qr-bill;';
116  return false;
117  }
118 
119  // Create a new instance of SwissQrBill, containing default headers with fixed values
120  $qrBill = SwissQrBill\QrBill::create();
121 
122  // First, set creditor address
123  $address = SwissQrBill\DataGroup\Element\CombinedAddress::create(
124  $this->emetteur->name,
125  $this->emetteur->address,
126  $this->emetteur->zip . " " . $this->emetteur->town,
127  $this->emetteur->country_code
128  );
129  if (!$address->isValid()) {
130  $this->error = $langs->transnoentities("SwissQrCreditorAddressInvalid", (string) $address->getViolations());
131  return false;
132  }
133  $qrBill->setCreditor($address);
134 
135  // Get IBAN from account.
136  $account = new Account($this->db);
137  $account->fetch($object->fk_account);
138  $creditorInformation = SwissQrBill\DataGroup\Element\CreditorInformation::create($account->iban);
139  if (!$creditorInformation->isValid()) {
140  $langs->load("errors");
141  $this->error = $langs->transnoentities("SwissQrCreditorInformationInvalid", $account->iban, (string) $creditorInformation->getViolations());
142  return false;
143  }
144  $qrBill->setCreditorInformation($creditorInformation);
145 
146  if ($creditorInformation->containsQrIban()) {
147  $this->error = $langs->transnoentities("SwissQrIbanNotImplementedYet", $account->iban);
148  return false;
149  }
150 
151  // Add payment reference CLASSIC-IBAN
152  // This is what you will need to identify incoming payments.
153  $qrBill->setPaymentReference(
154  SwissQrBill\DataGroup\Element\PaymentReference::create(
155  SwissQrBill\DataGroup\Element\PaymentReference::TYPE_NON
156  )
157  );
158 
159  $currencyinvoicecode = $object->multicurrency_code ? $object->multicurrency_code : $conf->currency;
160 
161  // Add payment amount, with currency
162  $pai = SwissQrBill\DataGroup\Element\PaymentAmountInformation::create($currencyinvoicecode, $object->total_ttc);
163  if (!$pai->isValid()) {
164  $this->error = $langs->transnoentities("SwissQrPaymentInformationInvalid", $object->total_ttc, (string) $pai->getViolations());
165  return false;
166  }
167  $qrBill->setPaymentAmountInformation($pai);
168 
169  // Add some human-readable information about what the bill is for.
170  $qrBill->setAdditionalInformation(
171  SwissQrBill\DataGroup\Element\AdditionalInformation::create(
172  $object->ref
173  )
174  );
175 
176  // Set debtor address; We _know_ zip&town have to be filled, so skip that if unfilled.
177  if (!empty($object->thirdparty->zip) && !empty($object->thirdparty->town)) {
178  $address = SwissQrBill\DataGroup\Element\CombinedAddress::create(
179  $object->thirdparty->name,
180  $object->thirdparty->address,
181  $object->thirdparty->zip . " " . $object->thirdparty->town,
182  $object->thirdparty->country_code
183  );
184  if (!$address->isValid()) {
185  $this->error = $langs->transnoentities("SwissQrDebitorAddressInvalid", (string) $address->getViolations());
186  return false;
187  }
188  $qrBill->setUltimateDebtor($address);
189  }
190 
191  return $qrBill;
192  }
193 
202  protected function getHeightForQRInvoice(int $pagenbr, Facture $object, Translate $langs) : int
203  {
204  if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') == 'bottom') {
205  // Keep it, to reset it after QRinvoice getter
206  $error = $this->error;
207 
208  if (!$this->getSwissQrBill($object, $langs)) {
209  // Reset error to previous one if exists
210  if (!empty($error)) {
211  $this->error = $error;
212  }
213  return 0;
214  }
215  // SWIFT's requirementis 105, but we get more room with 100 and the page number is in a nice place.
216  return $pagenbr == 1 ? 100 : 0;
217  }
218 
219  return 0;
220  }
221 
230  public function addBottomQRInvoice(TCPDF $pdf, Facture $object, Translate $langs) : bool
231  {
232  if (!($qrBill = $this->getSwissQrBill($object, $langs))) {
233  return false;
234  }
235 
236  try {
237  $pdf->startTransaction();
238 
239  $pdf->setPage(1);
240  $pdf->SetTextColor(0, 0, 0);
241  $output = new SwissQrBill\PaymentPart\Output\TcPdfOutput\TcPdfOutput($qrBill, in_array($langs->shortlang, ['de', 'fr', 'it']) ? $langs->shortlang : 'en', $pdf);
242  $output->setPrintable(false)->getPaymentPart();
243  } catch (Exception $e) {
244  $pdf->rollbackTransaction(true);
245  return false;
246  }
247  return true;
248  }
249 }
250 
254 abstract class ModeleNumRefFactures
255 {
259  public $error = '';
260 
261  public $version;
262 
263 
269  public function isEnabled()
270  {
271  return true;
272  }
273 
279  public function info()
280  {
281  global $langs;
282  $langs->load("bills");
283  return $langs->trans("NoDescription");
284  }
285 
291  public function getExample()
292  {
293  global $langs;
294  $langs->load("bills");
295  return $langs->trans("NoExample");
296  }
297 
304  public function canBeActivated()
305  {
306  return true;
307  }
308 
317  public function getNextValue($objsoc, $invoice, $mode = 'next')
318  {
319  global $langs;
320  return $langs->trans("NotAvailable");
321  }
322 
328  public function getVersion()
329  {
330  global $langs;
331  $langs->load("admin");
332 
333  if ($this->version == 'development') {
334  return $langs->trans("VersionDevelopment");
335  } elseif ($this->version == 'experimental') {
336  return $langs->trans("VersionExperimental");
337  } elseif ($this->version == 'dolibarr') {
338  return DOL_VERSION;
339  } elseif ($this->version) {
340  return $this->version;
341  } else {
342  return $langs->trans("NotAvailable");
343  }
344  }
345 }
Translate
Class to manage translations.
Definition: translate.class.php:30
ModelePDFFactures\liste_modeles
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Definition: modules_facture.php:72
Facture
Class to manage invoices.
Definition: facture.class.php:60
ModelePDFFactures
Parent class of invoice document generators.
Definition: modules_facture.php:40
ModelePDFFactures\getHeightForQRInvoice
getHeightForQRInvoice(int $pagenbr, Facture $object, Translate $langs)
Get the height for bottom-page QR invoice in mm, depending on the page number.
Definition: modules_facture.php:202
Exception
ModeleNumRefFactures
Parent class of invoice reference numbering templates.
Definition: modules_facture.php:254
ModeleNumRefFactures\getVersion
getVersion()
Renvoi version du modele de numerotation.
Definition: modules_facture.php:328
getListOfModels
getListOfModels($db, $type, $maxfilenamelength=0)
Return list of activated modules usable for document generation.
Definition: functions2.lib.php:1925
getDolGlobalString
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
Definition: functions.lib.php:142
ModeleNumRefFactures\info
info()
Returns the default description of the numbering pattern.
Definition: modules_facture.php:279
ModeleNumRefFactures\getNextValue
getNextValue($objsoc, $invoice, $mode='next')
Renvoi prochaine valeur attribuee.
Definition: modules_facture.php:317
ModeleNumRefFactures\isEnabled
isEnabled()
Return if a module can be used or not.
Definition: modules_facture.php:269
CommonDocGenerator
Parent class for documents generators.
Definition: commondocgenerator.class.php:36
ModelePDFFactures\addBottomQRInvoice
addBottomQRInvoice(TCPDF $pdf, Facture $object, Translate $langs)
Add SwissQR invoice at bottom of page 1.
Definition: modules_facture.php:230
ModeleNumRefFactures\getExample
getExample()
Return an example of numbering.
Definition: modules_facture.php:291
ModeleNumRefFactures\canBeActivated
canBeActivated()
Checks if the numbers already in the database do not cause conflicts that would prevent this numberin...
Definition: modules_facture.php:304
Account
Class to manage bank accounts.
Definition: account.class.php:40
ModelePDFFactures\getSwissQrBill
getSwissQrBill(Facture $object, Translate $langs)
Get the SwissQR object, including validation.
Definition: modules_facture.php:91