dolibarr 21.0.0-beta
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 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{
45 public $posxpicture;
46 public $posxtva;
47 public $posxup;
48 public $posxqty;
49 public $posxunit;
50 public $posxdesc;
51 public $posxdiscount;
52 public $postotalht;
53
54 public $tva;
55 public $tva_array;
56 public $localtax1;
57 public $localtax2;
58
59 public $atleastonediscount = 0;
60 public $atleastoneratenotnull = 0;
61
62
63 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
71 public static function liste_modeles($db, $maxfilenamelength = 0)
72 {
73 // phpcs:enable
74 $type = 'invoice';
75 $list = array();
76
77 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
78 $list = getListOfModels($db, $type, $maxfilenamelength);
79
80 return $list;
81 }
82
83
84 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
96 abstract public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0);
97 // phpcs:enable
98
99
107 private function getSwissQrBill(Facture $object, Translate $langs)
108 {
109 global $conf;
110
111 if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') != 'bottom') {
112 return false;
113 }
114
115 if ($object->mode_reglement_code != 'VIR') {
116 $this->error = $langs->transnoentities("SwissQrOnlyVIR");
117 return false;
118 }
119
120 if (empty($object->fk_account)) {
121 $this->error = 'Bank account must be defined to use this experimental feature';
122 return false;
123 }
124
125 // Load the autoload file generated by composer
126 if (file_exists(DOL_DOCUMENT_ROOT.'/includes/sprain/swiss-qr-bill/autoload.php')) {
127 require_once DOL_DOCUMENT_ROOT.'/includes/sprain/swiss-qr-bill/autoload.php'; // @phpstan-ignore-line
128 } elseif (file_exists(DOL_DOCUMENT_ROOT.'/includes/autoload.php')) {
129 require_once DOL_DOCUMENT_ROOT.'/includes/autoload.php'; // @phpstan-ignore-line
130 } else {
131 $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;';
132 return false;
133 }
134
135 // Create a new instance of SwissQrBill, containing default headers with fixed values
136 $qrBill = SwissQrBill\QrBill::create();
137
138 // First, set creditor address
139 $address = SwissQrBill\DataGroup\Element\CombinedAddress::create(
140 $this->emetteur->name,
141 $this->emetteur->address,
142 $this->emetteur->zip . " " . $this->emetteur->town,
143 $this->emetteur->country_code
144 );
145 if (!$address->isValid()) {
146 $this->error = $langs->transnoentities("SwissQrCreditorAddressInvalid", (string) $address->getViolations());
147 return false;
148 }
149 $qrBill->setCreditor($address);
150
151 // Get IBAN from account.
152 $account = new Account($this->db);
153 $account->fetch($object->fk_account);
154 $creditorInformation = SwissQrBill\DataGroup\Element\CreditorInformation::create($account->iban);
155 if (!$creditorInformation->isValid()) {
156 $langs->load("errors");
157 $this->error = $langs->transnoentities("SwissQrCreditorInformationInvalid", $account->iban, (string) $creditorInformation->getViolations());
158 return false;
159 }
160 $qrBill->setCreditorInformation($creditorInformation);
161
162 if ($creditorInformation->containsQrIban()) {
163 $this->error = $langs->transnoentities("SwissQrIbanNotImplementedYet", $account->iban);
164 return false;
165 }
166
167 // Add payment reference CLASSIC-IBAN
168 // This is what you will need to identify incoming payments.
169 $qrBill->setPaymentReference(
170 SwissQrBill\DataGroup\Element\PaymentReference::create(
171 SwissQrBill\DataGroup\Element\PaymentReference::TYPE_NON
172 )
173 );
174
175 $currencyinvoicecode = $object->multicurrency_code ? $object->multicurrency_code : $conf->currency;
176
177 // Add payment amount, with currency
178 $pai = SwissQrBill\DataGroup\Element\PaymentAmountInformation::create($currencyinvoicecode, $object->total_ttc);
179 if (!$pai->isValid()) {
180 $this->error = $langs->transnoentities("SwissQrPaymentInformationInvalid", $object->total_ttc, (string) $pai->getViolations());
181 return false;
182 }
183 $qrBill->setPaymentAmountInformation($pai);
184
185 // Add some human-readable information about what the bill is for.
186 $qrBill->setAdditionalInformation(
187 SwissQrBill\DataGroup\Element\AdditionalInformation::create(
188 $object->ref
189 )
190 );
191
192 // Set debtor address; We _know_ zip&town have to be filled, so skip that if unfilled.
193 if (!empty($object->thirdparty->zip) && !empty($object->thirdparty->town)) {
194 $address = SwissQrBill\DataGroup\Element\CombinedAddress::create(
195 $object->thirdparty->name,
196 $object->thirdparty->address,
197 $object->thirdparty->zip . " " . $object->thirdparty->town,
198 $object->thirdparty->country_code
199 );
200 if (!$address->isValid()) {
201 $this->error = $langs->transnoentities("SwissQrDebitorAddressInvalid", (string) $address->getViolations());
202 return false;
203 }
204 $qrBill->setUltimateDebtor($address);
205 }
206
207 return $qrBill;
208 }
209
218 protected function getHeightForQRInvoice(int $pagenbr, Facture $object, Translate $langs)
219 {
220 if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') == 'bottom') {
221 // Keep it, to reset it after QRinvoice getter
222 $error = $this->error;
223
224 if (!$this->getSwissQrBill($object, $langs)) {
225 // Reset error to previous one if exists
226 if (!empty($error)) {
227 $this->error = $error;
228 }
229 return 0;
230 }
231 // SWIFT's requirementis 105, but we get more room with 100 and the page number is in a nice place.
232 return $pagenbr == 1 ? 100 : 0;
233 }
234
235 return 0;
236 }
237
246 public function addBottomQRInvoice(TCPDF $pdf, Facture $object, Translate $langs): bool
247 {
248 if (!($qrBill = $this->getSwissQrBill($object, $langs))) {
249 return false;
250 }
251
252 try {
253 $pdf->startTransaction();
254
255 $pdf->setPage(1);
256 $pdf->SetTextColor(0, 0, 0);
257 $output = new SwissQrBill\PaymentPart\Output\TcPdfOutput\TcPdfOutput($qrBill, in_array($langs->shortlang, ['de', 'fr', 'it']) ? $langs->shortlang : 'en', $pdf);
258 $output->setPrintable(false)->getPaymentPart();
259 } catch (Exception $e) {
260 $pdf->rollbackTransaction(true);
261 return false;
262 }
263 return true;
264 }
265}
266
271{
280 abstract public function getNextValue($objsoc, $invoice, $mode = 'next');
281
287 abstract public function getExample();
288}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
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)
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