1<?php 2/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> 3 * Copyright (C) 2010 Laurent Destailleur <eldy@users.sourceforge.net> 4 * Copyright (C) 2019 Alexandre Spangaro <aspangaro@open-dsi.fr> 5 * Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr> 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 22/** 23 * \file htdocs/core/modules/societe/mod_codecompta_digitaria.php 24 * \ingroup societe 25 * \brief File of class to manage accountancy code of thirdparties with Digitaria rules 26 */ 27require_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php'; 28 29 30/** 31 * Class to manage accountancy code of thirdparties with Digitaria rules 32 */ 33class mod_codecompta_digitaria extends ModeleAccountancyCode 34{ 35 /** 36 * @var string model name 37 */ 38 public $name = 'Digitaria'; 39 40 /** 41 * Dolibarr version of the loaded document 42 * @var string 43 */ 44 public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' 45 46 /** 47 * Prefix customer accountancy code 48 * @var string 49 */ 50 public $prefixcustomeraccountancycode; 51 52 /** 53 * Prefix supplier accountancy code 54 * @var string 55 */ 56 public $prefixsupplieraccountancycode; 57 58 public $position = 30; 59 60 61 /** 62 * Constructor 63 */ 64 public function __construct() 65 { 66 global $conf, $langs; 67 if (!isset($conf->global->COMPANY_DIGITARIA_MASK_CUSTOMER) || trim($conf->global->COMPANY_DIGITARIA_MASK_CUSTOMER) == '') { 68 $conf->global->COMPANY_DIGITARIA_MASK_CUSTOMER = '411'; 69 } 70 if (!isset($conf->global->COMPANY_DIGITARIA_MASK_SUPPLIER) || trim($conf->global->COMPANY_DIGITARIA_MASK_SUPPLIER) == '') { 71 $conf->global->COMPANY_DIGITARIA_MASK_SUPPLIER = '401'; 72 } 73 $this->prefixcustomeraccountancycode = $conf->global->COMPANY_DIGITARIA_MASK_CUSTOMER; 74 $this->prefixsupplieraccountancycode = $conf->global->COMPANY_DIGITARIA_MASK_SUPPLIER; 75 76 if (!isset($conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_CUSTOMER) || trim($conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_CUSTOMER) == '') { 77 $conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_CUSTOMER = '5'; 78 } 79 if (!isset($conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_SUPPLIER) || trim($conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_SUPPLIER) == '') { 80 $conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_SUPPLIER = '5'; 81 } 82 $this->customeraccountancycodecharacternumber = $conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_CUSTOMER; 83 $this->supplieraccountancycodecharacternumber = $conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_SUPPLIER; 84 } 85 86 /** 87 * Return description of module 88 * 89 * @param Translate $langs Object langs 90 * @return string Description of module 91 */ 92 public function info($langs) 93 { 94 global $conf, $form; 95 96 $tooltip = ''; 97 $texte = '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; 98 $texte .= '<input type="hidden" name="token" value="'.newToken().'">'; 99 $texte .= '<input type="hidden" name="action" value="setModuleOptions">'; 100 $texte .= '<input type="hidden" name="param1" value="COMPANY_DIGITARIA_MASK_SUPPLIER">'; 101 $texte .= '<input type="hidden" name="param2" value="COMPANY_DIGITARIA_MASK_CUSTOMER">'; 102 $texte .= '<input type="hidden" name="param3" value="COMPANY_DIGITARIA_MASK_NBCHARACTER_SUPPLIER">'; 103 $texte .= '<input type="hidden" name="param4" value="COMPANY_DIGITARIA_MASK_NBCHARACTER_CUSTOMER">'; 104 $texte .= '<table class="nobordernopadding" width="100%">'; 105 $s1 = $form->textwithpicto('<input type="text" class="flat" size="4" name="value1" value="'.$conf->global->COMPANY_DIGITARIA_MASK_SUPPLIER.'">', $tooltip, 1, 1); 106 $s2 = $form->textwithpicto('<input type="text" class="flat" size="4" name="value2" value="'.$conf->global->COMPANY_DIGITARIA_MASK_CUSTOMER.'">', $tooltip, 1, 1); 107 $s3 = $form->textwithpicto('<input type="text" class="flat" size="2" name="value3" value="'.$conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_SUPPLIER.'">', $tooltip, 1, 1); 108 $s4 = $form->textwithpicto('<input type="text" class="flat" size="2" name="value4" value="'.$conf->global->COMPANY_DIGITARIA_MASK_NBCHARACTER_CUSTOMER.'">', $tooltip, 1, 1); 109 $texte .= '<tr><td>'; 110 // trans remove html entities 111 $texte .= $langs->trans("ModuleCompanyCodeCustomer".$this->name, '{s2}', '{s4}')."<br>\n"; 112 $texte .= $langs->trans("ModuleCompanyCodeSupplier".$this->name, '{s1}', '{s3}')."<br>\n"; 113 $texte = str_replace(array('{s1}', '{s2}', '{s3}', '{s4}'), array($s1, $s2, $s3, $s4), $texte); 114 $texte .= "<br>\n"; 115 // Remove special char if COMPANY_DIGITARIA_REMOVE_SPECIAL is set to 1 or not set (default) 116 if (!isset($conf->global->COMPANY_DIGITARIA_REMOVE_SPECIAL) || !empty($conf->global->$conf->global->COMPANY_DIGITARIA_REMOVE_SPECIAL)) { 117 $texte .= $langs->trans('RemoveSpecialChars').' = '.yn(1)."<br>\n"; 118 } 119 // Apply a regex replacement pattern on code if COMPANY_DIGITARIA_CLEAN_REGEX is set. Value must be a regex with parenthesis. The part into parenthesis is kept, the rest removed. 120 if (!empty($conf->global->COMPANY_DIGITARIA_CLEAN_REGEX)) { 121 $texte .= $langs->trans('COMPANY_DIGITARIA_CLEAN_REGEX').' = '.$conf->global->COMPANY_DIGITARIA_CLEAN_REGEX."<br>\n"; 122 } 123 // Unique index on code if COMPANY_DIGITARIA_UNIQUE_CODE is set to 1 or not set (default) 124 if (!isset($conf->global->COMPANY_DIGITARIA_UNIQUE_CODE) || !empty($conf->global->COMPANY_DIGITARIA_UNIQUE_CODE)) { 125 $texte .= $langs->trans('COMPANY_DIGITARIA_UNIQUE_CODE').' = '.yn(1)."<br>\n"; 126 } 127 $texte .= '</td>'; 128 $texte .= '<td class="right"><input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button"></td>'; 129 $texte .= '</tr></table>'; 130 $texte .= '</form>'; 131 132 return $texte; 133 } 134 135 /** 136 * Return an example of result returned by getNextValue 137 * 138 * @param Translate $langs Object langs 139 * @param Societe $objsoc Object thirdparty 140 * @param int $type Type of third party (1:customer, 2:supplier, -1:autodetect) 141 * @return string Example 142 */ 143 public function getExample($langs, $objsoc = 0, $type = -1) 144 { 145 global $conf, $mysoc; 146 147 $s = $langs->trans("ThirdPartyName").": ".$mysoc->name; 148 $s .= "<br>\n"; 149 150 if (!isset($conf->global->COMPANY_DIGITARIA_REMOVE_SPECIAL)) { 151 $thirdpartylabelexample = preg_replace('/([^a-z0-9])/i', '', $mysoc->name); 152 } 153 $s .= "<br>\n"; 154 $s .= $this->prefixcustomeraccountancycode.strtoupper(substr($thirdpartylabelexample, 0, $this->customeraccountancycodecharacternumber)); 155 $s .= "<br>\n"; 156 $s .= $this->prefixsupplieraccountancycode.strtoupper(substr($thirdpartylabelexample, 0, $this->supplieraccountancycodecharacternumber)); 157 return $s; 158 } 159 160 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 161 /** 162 * Set accountancy account code for a third party into this->code 163 * 164 * @param DoliDB $db Database handler 165 * @param Societe $societe Third party object 166 * @param int $type 'customer' or 'supplier' 167 * @return int >=0 if OK, <0 if KO 168 */ 169 public function get_code($db, $societe, $type = '') 170 { 171 // phpcs:enable 172 global $conf; 173 $i = 0; 174 $this->code = ''; 175 176 $disponibility = 0; 177 178 if (is_object($societe)) { 179 dol_syslog("mod_codecompta_digitaria::get_code search code for type=".$type." & company=".(!empty($societe->name) ? $societe->name : '')); 180 181 if ($type == 'supplier') { 182 $codetouse = $societe->name; 183 $prefix = $this->prefixsupplieraccountancycode; 184 $width = $this->supplieraccountancycodecharacternumber; 185 } elseif ($type == 'customer') { 186 $codetouse = $societe->name; 187 $prefix = $this->prefixcustomeraccountancycode; 188 $width = $this->customeraccountancycodecharacternumber; 189 } else { 190 $this->error = 'Bad value for parameter type'; 191 return -1; 192 } 193 194 // Remove special char if COMPANY_DIGITARIA_REMOVE_SPECIAL is set to 1 or not set (default) 195 if (!isset($conf->global->COMPANY_DIGITARIA_REMOVE_SPECIAL) || !empty($conf->global->COMPANY_DIGITARIA_REMOVE_SPECIAL)) { 196 $codetouse = preg_replace('/([^a-z0-9])/i', '', $codetouse); 197 } 198 // Apply a regex replacement pattern on code if COMPANY_DIGITARIA_CLEAN_REGEX is set. Value must be a regex with parenthesis. The part into parenthesis is kept, the rest removed. 199 if (!empty($conf->global->COMPANY_DIGITARIA_CLEAN_REGEX)) { // Example: $conf->global->COMPANY_DIGITARIA_CLEAN_REGEX='^..(..)..'; 200 $codetouse = preg_replace('/'.$conf->global->COMPANY_DIGITARIA_CLEAN_REGEX.'/', '\1\2\3', $codetouse); 201 } 202 203 $this->code = $prefix.strtoupper(substr($codetouse, 0, $width)); 204 dol_syslog("mod_codecompta_digitaria::get_code search code proposed=".$this->code); 205 206 // Unique index on code if COMPANY_DIGITARIA_UNIQUE_CODE is set to 1 or not set (default) 207 if (!isset($conf->global->COMPANY_DIGITARIA_UNIQUE_CODE) || !empty($conf->global->COMPANY_DIGITARIA_UNIQUE_CODE)) { 208 $disponibility = $this->checkIfAccountancyCodeIsAlreadyUsed($db, $this->code, $type); 209 210 while ($disponibility <> 0 && $i < 1000) { 211 $widthsupplier = $this->supplieraccountancycodecharacternumber; 212 $widthcustomer = $this->customeraccountancycodecharacternumber; 213 214 if ($i <= 9) { 215 $a = 1; 216 } 217 if ($i >= 10 && $i <= 99) { 218 $a = 2; 219 } 220 if ($i >= 100 && $i <= 999) { 221 $a = 3; 222 } 223 224 if ($type == 'supplier') { 225 $this->code = $prefix.strtoupper(substr($codetouse, 0, $widthsupplier - $a)).$i; 226 } elseif ($type == 'customer') { 227 $this->code = $prefix.strtoupper(substr($codetouse, 0, $widthcustomer - $a)).$i; 228 } 229 $disponibility = $this->checkIfAccountancyCodeIsAlreadyUsed($db, $this->code, $type); 230 231 $i++; 232 } 233 } else { 234 $disponibility == 0; 235 } 236 } 237 238 if ($disponibility == 0) { 239 return 0; // return ok 240 } else { 241 return -1; // return ko 242 } 243 } 244 245 /** 246 * Check accountancy account code for a third party into this->code 247 * 248 * @param DoliDB $db Database handler 249 * @param string $code Code of third party 250 * @param int $type 'customer' or 'supplier' 251 * @return int >=0 if OK, <0 if KO 252 */ 253 public function checkIfAccountancyCodeIsAlreadyUsed($db, $code, $type = '') 254 { 255 if ($type == 'supplier') { 256 $typethirdparty = 'code_compta_fournisseur'; 257 } elseif ($type == 'customer') { 258 $typethirdparty = 'code_compta'; 259 } else { 260 $this->error = 'Bad value for parameter type'; 261 return -1; 262 } 263 264 $sql = "SELECT ".$typethirdparty." FROM ".MAIN_DB_PREFIX."societe"; 265 $sql .= " WHERE ".$typethirdparty." = '".$db->escape($code)."'"; 266 267 $resql = $db->query($sql); 268 if ($resql) { 269 if ($db->num_rows($resql) == 0) { 270 dol_syslog("mod_codecompta_digitaria::checkIfAccountancyCodeIsAlreadyUsed '".$code."' available"); 271 return 0; // Available 272 } else { 273 dol_syslog("mod_codecompta_digitaria::checkIfAccountancyCodeIsAlreadyUsed '".$code."' not available"); 274 return -1; // Not available 275 } 276 } else { 277 $this->error = $db->error()." sql=".$sql; 278 return -2; // Error 279 } 280 } 281} 282