dolibarr  16.0.1
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  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  * or see https://www.gnu.org/
18  */
19 
25 require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
26 
32 {
37  public $version = 'dolibarr';
38 
43  public $prefixinvoice = 'FA';
44 
49  public $prefixreplacement = 'FA';
50 
55  public $prefixcreditnote = 'AV';
56 
61  public $prefixdeposit = 'AC';
62 
66  public $error = '';
67 
68 
72  public function __construct()
73  {
74  global $conf, $mysoc;
75 
76  if ((float) $conf->global->MAIN_VERSION_LAST_INSTALL >= 16.0 && $mysoc->country_code != 'FR') {
77  $this->prefixinvoice = 'IN'; // We use correct standard code "IN = Invoice"
78  $this->prefixreplacement = 'IR';
79  $this->prefixdeposit = 'ID';
80  $this->prefixcreditnote = 'IC';
81  }
82 
83  if (!empty($conf->global->INVOICE_NUMBERING_TERRE_FORCE_PREFIX)) {
84  $this->prefixinvoice = $conf->global->INVOICE_NUMBERING_TERRE_FORCE_PREFIX;
85  }
86  }
87 
93  public function info()
94  {
95  global $langs;
96  $langs->load("bills");
97  return $langs->trans('TerreNumRefModelDesc1', $this->prefixinvoice, $this->prefixcreditnote, $this->prefixdeposit);
98  }
99 
105  public function getExample()
106  {
107  return $this->prefixinvoice."0501-0001";
108  }
109 
116  public function canBeActivated()
117  {
118  global $langs, $conf, $db;
119 
120  $langs->load("bills");
121 
122  // Check invoice num
123  $fayymm = '';
124  $max = '';
125 
126  $posindice = strlen($this->prefixinvoice) + 6;
127  $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
128  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
129  $sql .= " WHERE ref LIKE '".$db->escape($this->prefixinvoice)."____-%'";
130  $sql .= " AND entity = ".$conf->entity;
131 
132  $resql = $db->query($sql);
133  if ($resql) {
134  $row = $db->fetch_row($resql);
135  if ($row) {
136  $fayymm = substr($row[0], 0, 6);
137  $max = $row[0];
138  }
139  }
140  if ($fayymm && !preg_match('/'.$this->prefixinvoice.'[0-9][0-9][0-9][0-9]/i', $fayymm)) {
141  $langs->load("errors");
142  $this->error = $langs->trans('ErrorNumRefModel', $max);
143  return false;
144  }
145 
146  // Check credit note num
147  $fayymm = '';
148 
149  $posindice = strlen($this->prefixcreditnote) + 6;
150  $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
151  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
152  $sql .= " WHERE ref LIKE '".$db->escape($this->prefixcreditnote)."____-%'";
153  $sql .= " AND entity = ".$conf->entity;
154 
155  $resql = $db->query($sql);
156  if ($resql) {
157  $row = $db->fetch_row($resql);
158  if ($row) {
159  $fayymm = substr($row[0], 0, 6);
160  $max = $row[0];
161  }
162  }
163  if ($fayymm && !preg_match('/'.$this->prefixcreditnote.'[0-9][0-9][0-9][0-9]/i', $fayymm)) {
164  $this->error = $langs->trans('ErrorNumRefModel', $max);
165  return false;
166  }
167 
168  // Check deposit num
169  $fayymm = '';
170 
171  $posindice = strlen($this->prefixdeposit) + 6;
172  $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
173  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
174  $sql .= " WHERE ref LIKE '".$db->escape($this->prefixdeposit)."____-%'";
175  $sql .= " AND entity = ".$conf->entity;
176 
177  $resql = $db->query($sql);
178  if ($resql) {
179  $row = $db->fetch_row($resql);
180  if ($row) {
181  $fayymm = substr($row[0], 0, 6);
182  $max = $row[0];
183  }
184  }
185  if ($fayymm && !preg_match('/'.$this->prefixdeposit.'[0-9][0-9][0-9][0-9]/i', $fayymm)) {
186  $this->error = $langs->trans('ErrorNumRefModel', $max);
187  return false;
188  }
189 
190  return true;
191  }
192 
204  public function getNextValue($objsoc, $invoice, $mode = 'next')
205  {
206  global $db;
207 
208  dol_syslog(get_class($this)."::getNextValue mode=".$mode, LOG_DEBUG);
209 
210  $prefix = $this->prefixinvoice;
211  if ($invoice->type == 2) {
212  $prefix = $this->prefixcreditnote;
213  } elseif ($invoice->type == 3) {
214  $prefix = $this->prefixdeposit;
215  }
216 
217  // First we get the max value
218  $posindice = strlen($prefix) + 6;
219  $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
220  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
221  $sql .= " WHERE ref LIKE '".$db->escape($prefix)."____-%'";
222  $sql .= " AND entity IN (".getEntity('invoicenumber', 1, $invoice).")";
223 
224  $resql = $db->query($sql);
225  if ($resql) {
226  $obj = $db->fetch_object($resql);
227  if ($obj) {
228  $max = intval($obj->max);
229  } else {
230  $max = 0;
231  }
232  } else {
233  return -1;
234  }
235 
236  if ($mode == 'last') {
237  if ($max >= (pow(10, 4) - 1)) {
238  $num = $max; // If counter > 9999, we do not format on 4 chars, we take number as it is
239  } else {
240  $num = sprintf("%04s", $max);
241  }
242 
243  $ref = '';
244  $sql = "SELECT ref as ref";
245  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
246  $sql .= " WHERE ref LIKE '".$db->escape($prefix)."____-".$num."'";
247  $sql .= " AND entity IN (".getEntity('invoicenumber', 1, $invoice).")";
248  $sql .= " ORDER BY ref DESC";
249 
250  $resql = $db->query($sql);
251  if ($resql) {
252  $obj = $db->fetch_object($resql);
253  if ($obj) {
254  $ref = $obj->ref;
255  }
256  } else {
257  dol_print_error($db);
258  }
259 
260  return $ref;
261  } elseif ($mode == 'next') {
262  $date = $invoice->date; // This is invoice date (not creation date)
263  $yymm = strftime("%y%m", $date);
264 
265  if ($max >= (pow(10, 4) - 1)) {
266  $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is
267  } else {
268  $num = sprintf("%04s", $max + 1);
269  }
270 
271  dol_syslog(get_class($this)."::getNextValue return ".$prefix.$yymm."-".$num);
272  return $prefix.$yymm."-".$num;
273  } else {
274  dol_print_error('', 'Bad parameter for getNextValue');
275  }
276 
277  return 0;
278  }
279 
288  public function getNumRef($objsoc, $objforref, $mode = 'next')
289  {
290  return $this->getNextValue($objsoc, $objforref, $mode);
291  }
292 }
info()
Returns the description of the numbering model.
Class of numbering module Terre for invoices.
canBeActivated()
Checks if the numbers already in the database do not cause conflicts that would prevent this numberin...
getNumRef($objsoc, $objforref, $mode= 'next')
Return next free value.
Parent class of invoice reference numbering templates.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->supplier_invoice->lire)) if(isModEnabled('don')&&!empty($user->rights->don->lire)) if(isModEnabled('tax')&&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture')&&isModEnabled('commande')&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
getExample()
Return an example of numbering.
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
__construct()
Constructor.
getNextValue($objsoc, $invoice, $mode= 'next')
Return next value not used or last value used.