dolibarr 18.0.6
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
26require_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 return -1;
237 }
238 }
239
248 public function getNumRef($objsoc, $objforref, $mode = 'next')
249 {
250 return $this->getNextValue($objsoc, $objforref, $mode);
251 }
252}
Parent class of invoice reference numbering templates.
Class to manage invoice numbering rules Mars.
getExample()
Return an example of numbering.
__construct()
Constructor.
getNextValue($objsoc, $invoice, $mode='next')
Return next value not used or last value used.
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.
info()
Returns the description of the numbering model.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.