dolibarr  16.0.1
mod_facture_mars.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-2018 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  * or see https://www.gnu.org/
19  */
20 
26 require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
27 
32 {
37  public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
38 
39  public $prefixinvoice = 'FA';
40 
41  public $prefixreplacement = 'FR';
42 
43  public $prefixdeposit = 'AC';
44 
45  public $prefixcreditnote = 'AV';
46 
50  public $error = '';
51 
52 
56  public function __construct()
57  {
58  global $conf, $mysoc;
59 
60  if ((float) $conf->global->MAIN_VERSION_LAST_INSTALL >= 16.0 && $mysoc->country_code != 'FR') {
61  $this->prefixinvoice = 'IN'; // We use correct standard code "IN = Invoice"
62  $this->prefixreplacement = 'IR';
63  $this->prefixdeposit = 'ID';
64  $this->prefixcreditnote = 'IC';
65  }
66 
67  if (!empty($conf->global->INVOICE_NUMBERING_MARS_FORCE_PREFIX)) {
68  $this->prefixinvoice = $conf->global->INVOICE_NUMBERING_MARS_FORCE_PREFIX;
69  }
70  }
71 
77  public function info()
78  {
79  global $langs;
80  $langs->load("bills");
81  return $langs->trans('MarsNumRefModelDesc1', $this->prefixinvoice, $this->prefixreplacement, $this->prefixdeposit, $this->prefixcreditnote);
82  }
83 
89  public function getExample()
90  {
91  return $this->prefixinvoice."0501-0001";
92  }
93 
100  public function canBeActivated()
101  {
102  global $langs, $conf, $db;
103 
104  $langs->load("bills");
105 
106  // Check invoice num
107  $fayymm = '';
108  $max = '';
109 
110  $posindice = strlen($this->prefixinvoice) + 6;
111  $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED) as max"; // This is standard SQL
112  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
113  $sql .= " WHERE ref LIKE '".$db->escape($this->prefixinvoice)."____-%'";
114  $sql .= " AND entity = ".$conf->entity;
115 
116  $resql = $db->query($sql);
117  if ($resql) {
118  $row = $db->fetch_row($resql);
119  if ($row) {
120  $fayymm = substr($row[0], 0, 6);
121  $max = $row[0];
122  }
123  }
124  if ($fayymm && !preg_match('/'.$this->prefixinvoice.'[0-9][0-9][0-9][0-9]/i', $fayymm)) {
125  $langs->load("errors");
126  $this->error = $langs->trans('ErrorNumRefModel', $max);
127  return false;
128  }
129 
130  // Check credit note num
131  $fayymm = '';
132 
133  $posindice = strlen($this->prefixcreditnote) + 6;
134  $sql = "SELECT MAX(SUBSTRING(ref FROM ".$posindice.")) as max"; // This is standard SQL
135  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
136  $sql .= " WHERE ref LIKE '".$db->escape($this->prefixcreditnote)."____-%'";
137  $sql .= " AND entity = ".$conf->entity;
138 
139  $resql = $db->query($sql);
140  if ($resql) {
141  $row = $db->fetch_row($resql);
142  if ($row) {
143  $fayymm = substr($row[0], 0, 6);
144  $max = $row[0];
145  }
146  }
147  if ($fayymm && !preg_match('/'.$this->prefixcreditnote.'[0-9][0-9][0-9][0-9]/i', $fayymm)) {
148  $this->error = $langs->trans('ErrorNumRefModel', $max);
149  return false;
150  }
151 
152  return true;
153  }
154 
163  public function getNextValue($objsoc, $invoice, $mode = 'next')
164  {
165  global $db;
166 
167  $prefix = $this->prefixinvoice;
168  if ($invoice->type == 1) {
169  $prefix = $this->prefixreplacement;
170  } elseif ($invoice->type == 2) {
171  $prefix = $this->prefixcreditnote;
172  } elseif ($invoice->type == 3) {
173  $prefix = $this->prefixdeposit;
174  }
175 
176  // First we get the max value
177  $posindice = strlen($prefix) + 6;
178  $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; // This is standard SQL
179  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
180  $sql .= " WHERE ref LIKE '".$db->escape($prefix)."____-%'";
181  $sql .= " AND entity IN (".getEntity('invoicenumber', 1, $invoice).")";
182 
183  $resql = $db->query($sql);
184  dol_syslog(get_class($this)."::getNextValue", LOG_DEBUG);
185  if ($resql) {
186  $obj = $db->fetch_object($resql);
187  if ($obj) {
188  $max = intval($obj->max);
189  } else {
190  $max = 0;
191  }
192  } else {
193  return -1;
194  }
195 
196  if ($mode == 'last') {
197  if ($max >= (pow(10, 4) - 1)) {
198  $num = $max; // If counter > 9999, we do not format on 4 chars, we take number as it is
199  } else {
200  $num = sprintf("%04s", $max);
201  }
202 
203  $ref = '';
204  $sql = "SELECT ref as ref";
205  $sql .= " FROM ".MAIN_DB_PREFIX."facture";
206  $sql .= " WHERE ref LIKE '".$db->escape($prefix)."____-".$num."'";
207  $sql .= " AND entity IN (".getEntity('invoicenumber', 1, $invoice).")";
208  $sql .= " ORDER BY ref DESC";
209 
210  dol_syslog(get_class($this)."::getNextValue", LOG_DEBUG);
211  $resql = $db->query($sql);
212  if ($resql) {
213  $obj = $db->fetch_object($resql);
214  if ($obj) {
215  $ref = $obj->ref;
216  }
217  } else {
218  dol_print_error($db);
219  }
220 
221  return $ref;
222  } elseif ($mode == 'next') {
223  $date = $invoice->date; // This is invoice date (not creation date)
224  $yymm = strftime("%y%m", $date);
225 
226  if ($max >= (pow(10, 4) - 1)) {
227  $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is
228  } else {
229  $num = sprintf("%04s", $max + 1);
230  }
231 
232  dol_syslog(get_class($this)."::getNextValue return ".$prefix.$yymm."-".$num);
233  return $prefix.$yymm."-".$num;
234  } else {
235  dol_print_error('', 'Bad parameter for getNextValue');
236  }
237  }
238 
247  public function getNumRef($objsoc, $objforref, $mode = 'next')
248  {
249  return $this->getNextValue($objsoc, $objforref, $mode);
250  }
251 }
getNumRef($objsoc, $objforref, $mode= 'next')
Return next free value.
Class to manage invoice numbering rules Mars.
getNextValue($objsoc, $invoice, $mode= 'next')
Return next value not used or last value used.
__construct()
Constructor.
Parent class of invoice reference numbering templates.
info()
Returns the description of the numbering model.
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...
canBeActivated()
Checks if the numbers already in the database do not cause conflicts that would prevent this numberin...