dolibarr 20.0.2
mod_facture_terre.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2005-2008 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2015 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * or see https://www.gnu.org/
20 */
21
27require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
28
34{
39 public $version = 'dolibarr';
40
45 public $prefixinvoice = 'FA';
46
51 public $prefixreplacement = 'FA';
52
57 public $prefixcreditnote = 'AV';
58
63 public $prefixdeposit = 'AC';
64
68 public $error = '';
69
70
74 public function __construct()
75 {
76 global $conf, $mysoc;
77
78 if (((float) getDolGlobalString('MAIN_VERSION_LAST_INSTALL')) >= 16.0 && $mysoc->country_code != 'FR') {
79 $this->prefixinvoice = 'IN'; // We use correct standard code "IN = Invoice"
80 $this->prefixreplacement = 'IR';
81 $this->prefixdeposit = 'ID';
82 $this->prefixcreditnote = 'IC';
83 }
84
85 if (getDolGlobalString('INVOICE_NUMBERING_TERRE_FORCE_PREFIX')) {
86 $this->prefixinvoice = getDolGlobalString('INVOICE_NUMBERING_TERRE_FORCE_PREFIX');
87 }
88 }
89
96 public function info($langs)
97 {
98 global $langs;
99 $langs->load("bills");
100 return $langs->trans('TerreNumRefModelDesc1', $this->prefixinvoice, $this->prefixcreditnote, $this->prefixdeposit);
101 }
102
108 public function getExample()
109 {
110 return $this->prefixinvoice."0501-0001";
111 }
112
120 public function canBeActivated($object)
121 {
122 global $langs, $conf, $db;
123
124 $langs->load("bills");
125
126 // Check invoice num
127 $fayymm = '';
128 $max = '';
129
130 $posindice = strlen($this->prefixinvoice) + 6;
131 $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
132 $sql .= " FROM ".MAIN_DB_PREFIX."facture";
133 $sql .= " WHERE ref LIKE '".$db->escape($this->prefixinvoice)."____-%'";
134 $sql .= " AND entity = ".$conf->entity;
135
136 $resql = $db->query($sql);
137 if ($resql) {
138 $row = $db->fetch_row($resql);
139 if ($row) {
140 $fayymm = substr($row[0], 0, 6);
141 $max = $row[0];
142 }
143 }
144 if ($fayymm && !preg_match('/'.$this->prefixinvoice.'[0-9][0-9][0-9][0-9]/i', $fayymm)) {
145 $langs->load("errors");
146 $this->error = $langs->trans('ErrorNumRefModel', $max);
147 return false;
148 }
149
150 // Check credit note num
151 $fayymm = '';
152
153 $posindice = strlen($this->prefixcreditnote) + 6;
154 $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
155 $sql .= " FROM ".MAIN_DB_PREFIX."facture";
156 $sql .= " WHERE ref LIKE '".$db->escape($this->prefixcreditnote)."____-%'";
157 $sql .= " AND entity = ".$conf->entity;
158
159 $resql = $db->query($sql);
160 if ($resql) {
161 $row = $db->fetch_row($resql);
162 if ($row) {
163 $fayymm = substr($row[0], 0, 6);
164 $max = $row[0];
165 }
166 }
167 if ($fayymm && !preg_match('/'.$this->prefixcreditnote.'[0-9][0-9][0-9][0-9]/i', $fayymm)) {
168 $this->error = $langs->trans('ErrorNumRefModel', $max);
169 return false;
170 }
171
172 // Check deposit num
173 $fayymm = '';
174
175 $posindice = strlen($this->prefixdeposit) + 6;
176 $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
177 $sql .= " FROM ".MAIN_DB_PREFIX."facture";
178 $sql .= " WHERE ref LIKE '".$db->escape($this->prefixdeposit)."____-%'";
179 $sql .= " AND entity = ".$conf->entity;
180
181 $resql = $db->query($sql);
182 if ($resql) {
183 $row = $db->fetch_row($resql);
184 if ($row) {
185 $fayymm = substr($row[0], 0, 6);
186 $max = $row[0];
187 }
188 }
189 if ($fayymm && !preg_match('/'.$this->prefixdeposit.'[0-9][0-9][0-9][0-9]/i', $fayymm)) {
190 $this->error = $langs->trans('ErrorNumRefModel', $max);
191 return false;
192 }
193
194 return true;
195 }
196
208 public function getNextValue($objsoc, $invoice, $mode = 'next')
209 {
210 global $db;
211
212 dol_syslog(get_class($this)."::getNextValue mode=".$mode, LOG_DEBUG);
213
214 $prefix = $this->prefixinvoice;
215 if ($invoice->type == 2) {
216 $prefix = $this->prefixcreditnote;
217 } elseif ($invoice->type == 3) {
218 $prefix = $this->prefixdeposit;
219 }
220
221 // First we get the max value
222 $posindice = strlen($prefix) + 6;
223 $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
224 $sql .= " FROM ".MAIN_DB_PREFIX."facture";
225 $sql .= " WHERE ref LIKE '".$db->escape($prefix)."____-%'";
226 $sql .= " AND entity IN (".getEntity('invoicenumber', 1, $invoice).")";
227
228 $resql = $db->query($sql);
229 if ($resql) {
230 $obj = $db->fetch_object($resql);
231 if ($obj) {
232 $max = intval($obj->max);
233 } else {
234 $max = 0;
235 }
236 } else {
237 return -1;
238 }
239
240 if ($mode == 'last') {
241 if ($max >= (pow(10, 4) - 1)) {
242 $num = $max; // If counter > 9999, we do not format on 4 chars, we take number as it is
243 } else {
244 $num = sprintf("%04d", $max);
245 }
246
247 $ref = '';
248 $sql = "SELECT ref as ref";
249 $sql .= " FROM ".MAIN_DB_PREFIX."facture";
250 $sql .= " WHERE ref LIKE '".$db->escape($prefix)."____-".$num."'";
251 $sql .= " AND entity IN (".getEntity('invoicenumber', 1, $invoice).")";
252 $sql .= " ORDER BY ref DESC";
253
254 $resql = $db->query($sql);
255 if ($resql) {
256 $obj = $db->fetch_object($resql);
257 if ($obj) {
258 $ref = $obj->ref;
259 }
260 } else {
261 dol_print_error($db);
262 }
263
264 return $ref;
265 } elseif ($mode == 'next') {
266 $date = $invoice->date; // This is invoice date (not creation date)
267 $yymm = dol_print_date($date, "%y%m");
268
269 if ($max >= (pow(10, 4) - 1)) {
270 $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is
271 } else {
272 $num = sprintf("%04d", $max + 1);
273 }
274
275 dol_syslog(get_class($this)."::getNextValue return ".$prefix.$yymm."-".$num);
276 return $prefix.$yymm."-".$num;
277 } else {
278 dol_print_error(null, 'Bad parameter for getNextValue');
279 }
280
281 return 0;
282 }
283
293 public function getNumRef($objsoc, $objforref, $mode = 'next')
294 {
295 return $this->getNextValue($objsoc, $objforref, $mode);
296 }
297}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
Parent class of invoice reference numbering templates.
Class of numbering module Terre for invoices.
getNextValue($objsoc, $invoice, $mode='next')
Return next value not used or last value used.
info($langs)
Returns the description of the numbering model.
getNumRef($objsoc, $objforref, $mode='next')
Return next free value.
getExample()
Return an example of numbering.
canBeActivated($object)
Checks if the numbers already in the database do not cause conflicts that would prevent this numberin...
__construct()
Constructor.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.