dolibarr 22.0.5
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 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 * or see https://www.gnu.org/
23 */
24
32require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/commonnumrefgenerator.class.php';
34require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
35require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Required because used in classes that inherit
36
37// For the experimental feature using swiss QR invoice generated by composer lib sparin/swiss-qr-bill
38use Sprain\SwissQrBill;
39
44{
48 public $posxpicture;
52 public $posxtva;
56 public $posxup;
60 public $posxqty;
64 public $posxunit;
68 public $posxdesc;
72 public $posxdiscount;
76 public $postotalht;
77
78
82 public $tva;
86 public $tva_array;
92 public $localtax1;
93
99 public $localtax2;
100
104 public $atleastonediscount = 0;
108 public $atleastoneratenotnull = 0;
109
110
111 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
119 public static function liste_modeles($db, $maxfilenamelength = 0)
120 {
121 // phpcs:enable
122 $type = 'invoice';
123 $list = array();
124
125 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
126 $list = getListOfModels($db, $type, $maxfilenamelength);
127
128 return $list;
129 }
130
131
132 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
144 abstract public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0);
145 // phpcs:enable
146
147
155 private function getSwissQrBill(Facture $object, Translate $langs)
156 {
157 global $conf;
158
159 if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') != 'bottom') {
160 return false;
161 }
162
163 if ($object->mode_reglement_code != 'VIR') {
164 $this->error = $langs->transnoentities("SwissQrOnlyVIR");
165 return false;
166 }
167
168 if (empty($object->fk_account)) {
169 $this->error = 'Bank account must be defined to use this experimental feature';
170 return false;
171 }
172
173 // Load the autoload file generated by composer
174 if (file_exists(DOL_DOCUMENT_ROOT.'/includes/sprain/swiss-qr-bill/autoload.php')) {
175 require_once DOL_DOCUMENT_ROOT.'/includes/sprain/swiss-qr-bill/autoload.php'; // @phpstan-ignore-line
176 } elseif (file_exists(DOL_DOCUMENT_ROOT.'/includes/autoload.php')) {
177 require_once DOL_DOCUMENT_ROOT.'/includes/autoload.php'; // @phpstan-ignore-line
178 } else {
179 $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;';
180 return false;
181 }
182
183 // Create a new instance of SwissQrBill, containing default headers with fixed values
184 $qrBill = SwissQrBill\QrBill::create();
185
186 // First, set creditor address
187 $address = SwissQrBill\DataGroup\Element\CombinedAddress::create(
188 $this->emetteur->name,
189 $this->emetteur->address,
190 $this->emetteur->zip . " " . $this->emetteur->town,
191 $this->emetteur->country_code
192 );
193 if (!$address->isValid()) {
194 $this->error = $langs->transnoentities("SwissQrCreditorAddressInvalid", (string) $address->getViolations());
195 return false;
196 }
197 $qrBill->setCreditor($address);
198
199 // Get IBAN from account.
200 $account = new Account($this->db);
201 $account->fetch($object->fk_account);
202 $creditorInformation = SwissQrBill\DataGroup\Element\CreditorInformation::create($account->iban);
203 if (!$creditorInformation->isValid()) {
204 $langs->load("errors");
205 $this->error = $langs->transnoentities("SwissQrCreditorInformationInvalid", $account->iban, (string) $creditorInformation->getViolations());
206 return false;
207 }
208 $qrBill->setCreditorInformation($creditorInformation);
209
210 if ($creditorInformation->containsQrIban()) {
211 $this->error = $langs->transnoentities("SwissQrIbanNotImplementedYet", $account->iban);
212 return false;
213 }
214
215 // Add payment reference CLASSIC-IBAN
216 // This is what you will need to identify incoming payments.
217 $qrBill->setPaymentReference(
218 SwissQrBill\DataGroup\Element\PaymentReference::create(
219 SwissQrBill\DataGroup\Element\PaymentReference::TYPE_NON
220 )
221 );
222
223 $currencyinvoicecode = $object->multicurrency_code ? $object->multicurrency_code : $conf->currency;
224
225 // Add payment amount, with currency
226 $pai = SwissQrBill\DataGroup\Element\PaymentAmountInformation::create($currencyinvoicecode, $object->total_ttc);
227 if (!$pai->isValid()) {
228 $this->error = $langs->transnoentities("SwissQrPaymentInformationInvalid", (string) $object->total_ttc, (string) $pai->getViolations());
229 return false;
230 }
231 $qrBill->setPaymentAmountInformation($pai);
232
233 // Add some human-readable information about what the bill is for.
234 $qrBill->setAdditionalInformation(
235 SwissQrBill\DataGroup\Element\AdditionalInformation::create(
236 $object->ref
237 )
238 );
239
240 // Set debtor address; We _know_ zip&town have to be filled, so skip that if unfilled.
241 if (!empty($object->thirdparty->zip) && !empty($object->thirdparty->town)) {
242 $address = SwissQrBill\DataGroup\Element\CombinedAddress::create(
243 $object->thirdparty->name,
244 $object->thirdparty->address,
245 $object->thirdparty->zip . " " . $object->thirdparty->town,
246 $object->thirdparty->country_code
247 );
248 if (!$address->isValid()) {
249 $this->error = $langs->transnoentities("SwissQrDebitorAddressInvalid", (string) $address->getViolations());
250 return false;
251 }
252 $qrBill->setUltimateDebtor($address);
253 }
254
255 return $qrBill;
256 }
257
266 protected function getHeightForQRInvoice(int $pagenbr, Facture $object, Translate $langs)
267 {
268 if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') == 'bottom') {
269 // Keep it, to reset it after QRinvoice getter
270 $error = $this->error;
271
272 if (!$this->getSwissQrBill($object, $langs)) {
273 // Reset error to previous one if exists
274 if (!empty($error)) {
275 $this->error = $error;
276 }
277 return 0;
278 }
279 // SWIFT's requirementis 105, but we get more room with 100 and the page number is in a nice place.
280 return $pagenbr == 1 ? 100 : 0;
281 }
282
283 return 0;
284 }
285
294 public function addBottomQRInvoice(TCPDF $pdf, Facture $object, Translate $langs): bool
295 {
296 if (!($qrBill = $this->getSwissQrBill($object, $langs))) {
297 return false;
298 }
299
300 try {
301 $pdf->startTransaction();
302
303 $pdf->setPage(1);
304 $pdf->SetTextColor(0, 0, 0);
305 $output = new SwissQrBill\PaymentPart\Output\TcPdfOutput\TcPdfOutput($qrBill, in_array($langs->shortlang, ['de', 'fr', 'it']) ? $langs->shortlang : 'en', $pdf);
306 $output->setPrintable(false)->getPaymentPart();
307 } catch (Exception $e) {
308 $pdf->rollbackTransaction(true);
309 return false;
310 }
311 return true;
312 }
313}
314
319{
328 abstract public function getNextValue($objsoc, $invoice, $mode = 'next');
329
335 abstract public function getExample();
336}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
Class to manage bank accounts.
Parent class for documents (PDF, ODT, ...) generators.
Parent class for number ref generators.
Class to manage invoices.
Parent class of invoice reference numbering templates.
getExample()
Return an example of numbering.
getNextValue($objsoc, $invoice, $mode='next')
Return next value not used or last value used.
Parent class of invoice document generators.
getSwissQrBill(Facture $object, Translate $langs)
Get the SwissQR object, including validation.
addBottomQRInvoice(TCPDF $pdf, Facture $object, Translate $langs)
Add SwissQR invoice at bottom of page 1.
getHeightForQRInvoice(int $pagenbr, Facture $object, Translate $langs)
Get the height for bottom-page QR invoice in mm, depending on the page number.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
Class to manage translations.
getListOfModels($db, $type, $maxfilenamelength=0, $showempty=0)
Return list of activated modules usable for document generation.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79