dolibarr 21.0.0-alpha
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 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 * or see https://www.gnu.org/
22 */
23
31require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/commonnumrefgenerator.class.php';
33require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
34require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Required because used in classes that inherit
35
36// For the experimental feature using swiss QR invoice generated by composer lib sparin/swiss-qr-bill
37use Sprain\SwissQrBill;
38
43{
44 public $posxpicture;
45 public $posxtva;
46 public $posxup;
47 public $posxqty;
48 public $posxunit;
49 public $posxdesc;
50 public $posxdiscount;
51 public $postotalht;
52
53 public $tva;
54 public $tva_array;
55 public $localtax1;
56 public $localtax2;
57
58 public $atleastonediscount = 0;
59 public $atleastoneratenotnull = 0;
60
61
62 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
70 public static function liste_modeles($db, $maxfilenamelength = 0)
71 {
72 // phpcs:enable
73 $type = 'invoice';
74 $list = array();
75
76 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
77 $list = getListOfModels($db, $type, $maxfilenamelength);
78
79 return $list;
80 }
81
82
83 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
95 abstract public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0);
96 // phpcs:enable
97
98
106 private function getSwissQrBill(Facture $object, Translate $langs)
107 {
108 global $conf;
109
110 if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') != 'bottom') {
111 return false;
112 }
113
114 if ($object->mode_reglement_code != 'VIR') {
115 $this->error = $langs->transnoentities("SwissQrOnlyVIR");
116 return false;
117 }
118
119 if (empty($object->fk_account)) {
120 $this->error = 'Bank account must be defined to use this experimental feature';
121 return false;
122 }
123
124 // Load the autoload file generated by composer
125 if (file_exists(DOL_DOCUMENT_ROOT.'/includes/sprain/swiss-qr-bill/autoload.php')) {
126 require_once DOL_DOCUMENT_ROOT.'/includes/sprain/swiss-qr-bill/autoload.php';
127 } elseif (file_exists(DOL_DOCUMENT_ROOT.'/includes/autoload.php')) {
128 require_once DOL_DOCUMENT_ROOT.'/includes/autoload.php';
129 } else {
130 $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;';
131 return false;
132 }
133
134 // Create a new instance of SwissQrBill, containing default headers with fixed values
135 $qrBill = SwissQrBill\QrBill::create();
136
137 // First, set creditor address
138 $address = SwissQrBill\DataGroup\Element\CombinedAddress::create(
139 $this->emetteur->name,
140 $this->emetteur->address,
141 $this->emetteur->zip . " " . $this->emetteur->town,
142 $this->emetteur->country_code
143 );
144 if (!$address->isValid()) {
145 $this->error = $langs->transnoentities("SwissQrCreditorAddressInvalid", (string) $address->getViolations());
146 return false;
147 }
148 $qrBill->setCreditor($address);
149
150 // Get IBAN from account.
151 $account = new Account($this->db);
152 $account->fetch($object->fk_account);
153 $creditorInformation = SwissQrBill\DataGroup\Element\CreditorInformation::create($account->iban);
154 if (!$creditorInformation->isValid()) {
155 $langs->load("errors");
156 $this->error = $langs->transnoentities("SwissQrCreditorInformationInvalid", $account->iban, (string) $creditorInformation->getViolations());
157 return false;
158 }
159 $qrBill->setCreditorInformation($creditorInformation);
160
161 if ($creditorInformation->containsQrIban()) {
162 $this->error = $langs->transnoentities("SwissQrIbanNotImplementedYet", $account->iban);
163 return false;
164 }
165
166 // Add payment reference CLASSIC-IBAN
167 // This is what you will need to identify incoming payments.
168 $qrBill->setPaymentReference(
169 SwissQrBill\DataGroup\Element\PaymentReference::create(
170 SwissQrBill\DataGroup\Element\PaymentReference::TYPE_NON
171 )
172 );
173
174 $currencyinvoicecode = $object->multicurrency_code ? $object->multicurrency_code : $conf->currency;
175
176 // Add payment amount, with currency
177 $pai = SwissQrBill\DataGroup\Element\PaymentAmountInformation::create($currencyinvoicecode, $object->total_ttc);
178 if (!$pai->isValid()) {
179 $this->error = $langs->transnoentities("SwissQrPaymentInformationInvalid", $object->total_ttc, (string) $pai->getViolations());
180 return false;
181 }
182 $qrBill->setPaymentAmountInformation($pai);
183
184 // Add some human-readable information about what the bill is for.
185 $qrBill->setAdditionalInformation(
186 SwissQrBill\DataGroup\Element\AdditionalInformation::create(
187 $object->ref
188 )
189 );
190
191 // Set debtor address; We _know_ zip&town have to be filled, so skip that if unfilled.
192 if (!empty($object->thirdparty->zip) && !empty($object->thirdparty->town)) {
193 $address = SwissQrBill\DataGroup\Element\CombinedAddress::create(
194 $object->thirdparty->name,
195 $object->thirdparty->address,
196 $object->thirdparty->zip . " " . $object->thirdparty->town,
197 $object->thirdparty->country_code
198 );
199 if (!$address->isValid()) {
200 $this->error = $langs->transnoentities("SwissQrDebitorAddressInvalid", (string) $address->getViolations());
201 return false;
202 }
203 $qrBill->setUltimateDebtor($address);
204 }
205
206 return $qrBill;
207 }
208
217 protected function getHeightForQRInvoice(int $pagenbr, Facture $object, Translate $langs)
218 {
219 if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') == 'bottom') {
220 // Keep it, to reset it after QRinvoice getter
221 $error = $this->error;
222
223 if (!$this->getSwissQrBill($object, $langs)) {
224 // Reset error to previous one if exists
225 if (!empty($error)) {
226 $this->error = $error;
227 }
228 return 0;
229 }
230 // SWIFT's requirementis 105, but we get more room with 100 and the page number is in a nice place.
231 return $pagenbr == 1 ? 100 : 0;
232 }
233
234 return 0;
235 }
236
245 public function addBottomQRInvoice(TCPDF $pdf, Facture $object, Translate $langs): bool
246 {
247 if (!($qrBill = $this->getSwissQrBill($object, $langs))) {
248 return false;
249 }
250
251 try {
252 $pdf->startTransaction();
253
254 $pdf->setPage(1);
255 $pdf->SetTextColor(0, 0, 0);
256 $output = new SwissQrBill\PaymentPart\Output\TcPdfOutput\TcPdfOutput($qrBill, in_array($langs->shortlang, ['de', 'fr', 'it']) ? $langs->shortlang : 'en', $pdf);
257 $output->setPrintable(false)->getPaymentPart();
258 } catch (Exception $e) {
259 $pdf->rollbackTransaction(true);
260 return false;
261 }
262 return true;
263 }
264}
265
270{
279 abstract public function getNextValue($objsoc, $invoice, $mode = 'next');
280
286 abstract public function getExample();
287}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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.