diff --git a/.travis.yml b/.travis.yml index 031226251c12181b8928809301a17cc8d6513a30..e3348e97b676f599f0077d26ce55a15d90e21bbe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,10 +18,15 @@ services: language: php php: # - "5.2" is not supported because pyrus to install PHP_Codesniffer is not available - - "5.3" - - "5.4" - - "5.5" - - "5.6" + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + +matrix: + allow_failures: + - php: 7.0 env: - DB=mysql diff --git a/ChangeLog b/ChangeLog index 7a5e1c7c5da94ddb956f5500ec9cf7b5c215e203..c94ceefcb5ba93a7727cf4c505d086c45707ccf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -226,6 +226,7 @@ Dolibarr better: - Fix: [ bug #1827 ] Tax reports gives incorrect amounts when using external modules that create lines with special codes - Fix: [ bug #1822 ] SQL error in clientfourn.php report with PostgreSQL - Fix: [ bug #1832 ] SQL error when adding a product with no price defined to an object +- Fix: [ bug #1833 ] user permissions in contact/note.php not working - Fix: [ bug #1826 ] Supplier payment types are not translated into fourn/facture/paiement.php - Fix: [ bug #1830 ] Salaries payment only allows checking accounts - Fix: [ bug #1825 ] External agenda: hide/show checkbox doesn't work diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 05402898ee6bbe0c16c6e86b6bfdfa4f17607bdf..8de52ef73c55ad7b998c291cb991eadf29da565d 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -8,7 +8,7 @@ * Copyright (C) 2011 Remy Younes <ryounes@gmail.com> * Copyright (C) 2012-2013 Marcos García <marcosgdf@gmail.com> * Copyright (C) 2012 Christophe Battarel <christophe.battarel@ltairis.fr> - * Copyright (C) 2011-2014 Alexandre Spangaro <alexandre.spangaro@gmail.com> + * Copyright (C) 2011-2015 Alexandre Spangaro <alexandre.spangaro@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -316,7 +316,7 @@ $tabcond[13]= (! empty($conf->commande->enabled) || ! empty($conf->propal->enabl $tabcond[14]= (! empty($conf->product->enabled) && ! empty($conf->ecotax->enabled)); $tabcond[15]= true; $tabcond[16]= (! empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)); -$tabcond[17]= ! empty($conf->deplacement->enabled); +$tabcond[17]= (! empty($conf->deplacement->enabled) || ! empty($conf->expensereport->enabled)); $tabcond[18]= ! empty($conf->expedition->enabled); $tabcond[19]= ! empty($conf->societe->enabled); $tabcond[20]= ! empty($conf->fournisseur->enabled); diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index a29c8e66b32d533c8b4b593a411c1613a10146f8..39b3dd4cad55d5262c96d89a033be74436e44fc0 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -66,6 +66,11 @@ else if ($conf->db->type == 'mssql') //$sqls[0] = ""; //$base=3; } +else if ($conf->db->type == 'sqlite' || $conf->db->type == 'sqlite3') +{ + //$sql = "SELECT name, type FROM sqlite_master"; + $base = 4; +} if (! $base) @@ -169,6 +174,40 @@ else } print '</table>'; } + + if ($base == 4) + { + // Sqlite by PDO or by Sqlite3 + print '<table class="noborder">'; + print '<tr class="liste_titre">'; + print '<td>'.$langs->trans("TableName").'</td>'; + print '<td>'.$langs->trans("NbOfRecord").'</td>'; + print "</tr>\n"; + + $sql = "SELECT name, type FROM sqlite_master where type='table' and name not like 'sqlite%' ORDER BY name"; + $resql = $db->query($sql); + + if ($resql) + { + $var=True; + while ($row = $db->fetch_row($resql)) { + + $rescount = $db->query("SELECT COUNT(*) FROM " . $row[0]); + if ($rescount) { + $row_count = $db->fetch_row($rescount); + $count = $row_count[0]; + } else { + $count = '?'; + } + + print "<tr ".$bc[$var].">"; + print '<td>'.$row[0].'</td>'; + print '<td>'.$count.'</td>'; + print '</tr>'; + } + } + + } } llxFooter(); diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 71c45be9eff26ce67952e2991e1a767f5f4c5451..431b7bd14b6f3be456fe600d246e18c9d0bd5156 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -5,6 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr> + * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -347,7 +348,6 @@ if (! empty($conf->use_javascript_ajax)) $s=''; $s.='<script type="text/javascript">' . "\n"; $s.='jQuery(document).ready(function () {' . "\n"; - $s.='jQuery("#check_mytasks").click(function() { jQuery(".family_mytasks").toggle(); jQuery(".family_other").toggle(); });' . "\n"; $s.='jQuery("#check_birthday").click(function() { jQuery(".family_birthday").toggle(); });' . "\n"; $s.='jQuery(".family_birthday").toggle();' . "\n"; if ($action=="show_week" || $action=="show_month" || empty($action)) @@ -361,18 +361,20 @@ if (! empty($conf->use_javascript_ajax)) $s.='<div class="nowrap clear float"><input type="checkbox" id="check_mytasks" name="check_mytasks" checked="true" disabled="disabled"> ' . $langs->trans("LocalAgenda").' </div>'; if (is_array($showextcals) && count($showextcals) > 0) { + $s.='<script type="text/javascript">' . "\n"; + $s.='jQuery(document).ready(function () { + jQuery("table input[name^=\"check_ext\"]").click(function() { + var name = $(this).attr("name"); + + jQuery(".family_ext" + name.replace("check_ext", "")).toggle(); + }); + });' . "\n"; + $s.='</script>' . "\n"; + foreach ($showextcals as $val) { $htmlname = md5($val['name']); - $s.='<script type="text/javascript">' . "\n"; - $s.='jQuery(document).ready(function () {' . "\n"; - $s.=' jQuery("#check_ext' . $htmlname . '").click(function() {'; - $s.=' /* alert("'.$htmlname.'"); */'; - $s.=' jQuery(".family_ext' . $htmlname . '").toggle();'; - $s.=' });' . "\n"; - $s.='});' . "\n"; - $s.='</script>' . "\n"; - $s.='<div class="nowrap float"><input type="checkbox" id="check_ext' . $htmlname . '" name="check_ext' . $htmlname . '" checked="true"> ' . $val ['name'] . ' </div>'; + $s.='<div class="nowrap float"><input type="checkbox" id="check_ext' . $htmlname . '" name="check_ext' . $htmlname . '" checked="true"> ' . $val['name'] . ' </div>'; } } $s.='<div class="nowrap float"><input type="checkbox" id="check_birthday" name="check_birthday"> '.$langs->trans("AgendaShowBirthdayEvents").' </div>'; diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 98f662e3d5ddb9db0342650ae02360bcb69c3e12..4a45f724f01f4fc17ddab44f7300e9c94ecad787 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -2003,8 +2003,7 @@ if ($action == 'create') // Amount HT print '<tr><td height="10" width="25%">' . $langs->trans('AmountHT') . '</td>'; - print '<td align="right" class="nowrap"><b>' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '</b></td>'; - print '<td></td>'; + print '<td align="right" class="nowrap" colspan="2"><b>' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '</b></td>'; // Margin Infos if (! empty($conf->margin->enabled)) { @@ -2016,27 +2015,27 @@ if ($action == 'create') // Amount VAT print '<tr><td height="10">' . $langs->trans('AmountVAT') . '</td>'; - print '<td align="right" class="nowrap">' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; - print '<td></td></tr>'; + print '<td align="right" class="nowrap" colspan="2">' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; + print '</tr>'; // Amount Local Taxes if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) // Localtax1 { print '<tr><td height="10">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>'; - print '<td align="right" class="nowrap">' . price($object->total_localtax1, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; + print '<td align="right" class="nowrap" colspan="2">' . price($object->total_localtax1, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; print '<td></td></tr>'; } if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) // Localtax2 { print '<tr><td height="10">' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>'; - print '<td align="right" class="nowrap">' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; - print '<td></td></tr>'; + print '<td align="right" class="nowrap" colspan="2">' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; + print '</tr>'; } // Amount TTC print '<tr><td height="10">' . $langs->trans('AmountTTC') . '</td>'; - print '<td align="right" class="nowrap">' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; - print '<td></td></tr>'; + print '<td align="right" class="nowrap" colspan="2">' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>'; + print '</tr>'; // Statut print '<tr><td height="10">' . $langs->trans('Status') . '</td><td align="left" colspan="2">' . $object->getLibStatut(4) . '</td></tr>'; diff --git a/htdocs/compta/hrm.php b/htdocs/compta/hrm.php index 866399ef1cc5b435af72fdd596d0580e18ada543..59389f41d51abbe085f3a9398b95afe1845fc26b 100644 --- a/htdocs/compta/hrm.php +++ b/htdocs/compta/hrm.php @@ -196,7 +196,7 @@ if (! empty($conf->deplacement->enabled) && $user->rights->deplacement->lire) if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire) { - $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, x.rowid, x.date_debut as date, x.tms as dm, x.total_ttc"; + $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, x.rowid, x.date_debut as date, x.tms as dm, x.total_ttc, x.fk_statut as status"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as x, ".MAIN_DB_PREFIX."user as u"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE u.rowid = x.fk_user_author"; @@ -218,7 +218,7 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire print '<table class="noborder" width="100%">'; print '<tr class="liste_titre">'; print '<td colspan="2">'.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).'</td>'; - print '<td align="right">'.$langs->trans("FeesAmount").'</td>'; + print '<td align="right">'.$langs->trans("TotalTTC").'</td>'; print '<td align="right">'.$langs->trans("DateModificationShort").'</td>'; print '<td width="16"> </td>'; print '</tr>'; @@ -239,9 +239,9 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire print '<tr '.$bc[$var].'>'; print '<td>'.$expensereportstatic->getNomUrl(1).'</td>'; print '<td>'.$userstatic->getNomUrl(1).'</td>'; - print '<td align="right">'.$obj->total_ttc.'</td>'; + print '<td align="right">'.price($obj->total_ttc).'</td>'; print '<td align="right">'.dol_print_date($db->jdate($obj->dm),'day').'</td>'; - //print '<td>'.$expensereportstatic->LibStatut($obj->fk_statut,3).'</td>'; + print '<td>'.$expensereportstatic->LibStatut($obj->status,3).'</td>'; print '</tr>'; $var=!$var; $i++; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index b2ec0de3ad50543db18f60d16ece40b501808abf..e977712ab39b9d2d003eb67cd660454464e68890 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1294,7 +1294,7 @@ class BonPrelevement extends CommonObject while ($i < $num) { $obj = $this->db->fetch_object($resql); - $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $ListOfFactures, $obj->idfac, $obj->iban, $obj->bic, $obj->datec, $obj->drum); + $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $ListOfFactures, $obj->idfac, $obj->iban, $obj->bic, $this->db->jdate($obj->datec), $obj->drum); $this->total = $this->total + $obj->somme; $i++; } @@ -1496,6 +1496,20 @@ class BonPrelevement extends CommonObject } + /** + * Build RUM number for a customer bank account + * + * @param string $row_code_client Customer code (soc.code_client) + * @param int $row_datec Creation date of bank account (rib.datec) + * @param string $row_drum Id of customer bank account (rib.rowid) + * @return string RUM number + */ + static function buildRumNumber($row_code_client, $row_datec, $row_drum) + { + $pre = ($row_datec > 1359673200) ? 'Rum' : '++R'; + return $pre.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec); + } + /** * Write recipient of request (customer) * @@ -1514,7 +1528,7 @@ class BonPrelevement extends CommonObject * @param string $row_iban rib.iban_prefix AS iban, * @param string $row_bic rib.bic AS bic, * @param string $row_datec rib.datec, - * @param string $row_drum rib.rowid AS drum + * @param string $row_drum rib.rowid used to generate rum * @return string Return string with SEPA part DrctDbtTxInf */ function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_facnumber, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum) @@ -1524,10 +1538,11 @@ class BonPrelevement extends CommonObject // Define value for RUM // Example: RUMCustomerCode-CustomerBankAccountId-01424448606 (note: Date is date of creation of CustomerBankAccountId) - $Date_Rum = strtotime($row_datec); + $Rum = $this->buildRumNumber($row_code_client, $row_datec, $row_drum); + + // Define date of RUM signature $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); - $pre = ($date_Rum > 1359673200) ? 'Rum' : '++R'; - $Rum = $pre.$row_code_client.$row_drum.'-0'.date('U', $Date_Rum); + $XML_DEBITOR =''; $XML_DEBITOR .=' <DrctDbtTxInf>'.$CrLf; $XML_DEBITOR .=' <PmtId>'.$CrLf; diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php index 3bd93659b5e67097e0f1878626d41ccae2775f2e..43e53140d35da084197b5b3f415382acc6fc4733 100644 --- a/htdocs/compta/salaries/card.php +++ b/htdocs/compta/salaries/card.php @@ -373,7 +373,7 @@ if ($id) print "<div class=\"tabsAction\">\n"; if ($salpayment->rappro == 0) { - if (! empty($user->rights->tax->charges->supprimer)) + if (! empty($user->rights->salaries->delete)) { print '<a class="butActionDelete" href="card.php?id='.$salpayment->id.'&action=delete">'.$langs->trans("Delete").'</a>'; } diff --git a/htdocs/conf/phpinfo.php b/htdocs/conf/phpinfo.php new file mode 100644 index 0000000000000000000000000000000000000000..179bd65145872e798bd194ecf7a750d6b37d4e61 --- /dev/null +++ b/htdocs/conf/phpinfo.php @@ -0,0 +1,5 @@ +<a href="index.php">Go back to index</a> +| <a href="<?php echo $_SERVER["REQUEST_URI"];?>">Refresh</a> +<br><br> + +<?php phpinfo(); ?> \ No newline at end of file diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index d6be5f4c0f4ef376b76c418b25903133633c6f42..82563549675e8cad3a696964a6e8edd4164cd2fd 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -73,7 +73,7 @@ $object = new Contrat($db); $extrafields = new ExtraFields($db); // Load object -if ($id > 0 || ! empty($ref)) { +if ($id > 0 || ! empty($ref) && $action!='add') { $ret = $object->fetch($id, $ref); if ($ret > 0) $ret = $object->fetch_thirdparty(); @@ -207,6 +207,13 @@ if ($action == 'add' && $user->rights->contrat->creer) $error++; } + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) { + $error ++; + $action = 'create'; + } + if (! $error) { $object->socid = $socid; @@ -356,11 +363,6 @@ if ($action == 'add' && $user->rights->contrat->creer) } else { - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) $error++; - $result = $object->create($user); if ($result > 0) { @@ -726,20 +728,19 @@ else if ($action == 'confirm_move' && $confirm == 'yes' && $user->rights->contra // Fill array 'array_options' with data from update form $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); - if ($ret < 0) $error++; + if ($ret < 0) + $error ++; - if (! $error) - { - $result = $object->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - else if ($reshook < 0) $error++; + if (! $error) { - if ($error) - { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + + if ($error) { $action = 'edit_extras'; setEventMessage($object->error,'errors'); } diff --git a/htdocs/contrat/class/index.html b/htdocs/contrat/class/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 02ccd13b97ca5e787cbcc05ee49d159a2271ab89..114648fdf143bc789475b620e55713108484fb6f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2140,7 +2140,7 @@ abstract class CommonObject $fieldstatus="fk_statut"; if ($elementTable == 'user') $fieldstatus="statut"; - if ($elementTable == 'expensereport') $fieldstatus="fk_c_expensereport_statuts"; + if ($elementTable == 'expensereport') $fieldstatus="fk_statut"; if ($elementTable == 'commande_fournisseur_dispatch') $fieldstatus="status"; $sql = "UPDATE ".MAIN_DB_PREFIX.$elementTable; diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index c400dc151d3c523cce3e555791b437802935edd4..d783445f276010801eb36539a1f50d8fa238ca45 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -65,7 +65,7 @@ class DolGraph var $bgcolorgrid=array(255,255,255); // array(R,G,B) var $datacolor; // array(array(R,G,B),...) - private $_stringtoshow; // To store string to output graph into HTML page + protected $stringtoshow; // To store string to output graph into HTML page /** @@ -774,7 +774,7 @@ class DolGraph // Generate file $graph->draw($file); - $this->_stringtoshow='<!-- Build using '.$this->_library.' --><img src="'.$fileurl.'" title="'.dol_escape_htmltag($this->title?$this->title:$this->YLabel).'" alt="'.dol_escape_htmltag($this->title?$this->title:$this->YLabel).'">'; + $this->stringtoshow='<!-- Build using '.$this->_library.' --><img src="'.$fileurl.'" title="'.dol_escape_htmltag($this->title?$this->title:$this->YLabel).'" alt="'.dol_escape_htmltag($this->title?$this->title:$this->YLabel).'">'; } @@ -847,18 +847,18 @@ class DolGraph } $tag=dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file),'_',array('-','.')))); - $this->_stringtoshow ='<!-- Build using '.$this->_library.' -->'."\n"; - if (! empty($this->title)) $this->_stringtoshow.='<div align="center" class="dolgraphtitle'.(empty($this->cssprefix)?'':' dolgraphtitle'.$this->cssprefix).'">'.$this->title.'</div>'; - $this->_stringtoshow.='<div id="placeholder_'.$tag.'" style="width:'.$this->width.'px;height:'.$this->height.'px;" class="dolgraph'.(empty($this->cssprefix)?'':' dolgraph'.$this->cssprefix).'"></div>'."\n"; - $this->_stringtoshow.='<script id="'.$tag.'">'."\n"; - $this->_stringtoshow.='$(function () {'."\n"; + $this->stringtoshow ='<!-- Build using '.$this->_library.' -->'."\n"; + if (! empty($this->title)) $this->stringtoshow.='<div align="center" class="dolgraphtitle'.(empty($this->cssprefix)?'':' dolgraphtitle'.$this->cssprefix).'">'.$this->title.'</div>'; + $this->stringtoshow.='<div id="placeholder_'.$tag.'" style="width:'.$this->width.'px;height:'.$this->height.'px;" class="dolgraph'.(empty($this->cssprefix)?'':' dolgraph'.$this->cssprefix).'"></div>'."\n"; + $this->stringtoshow.='<script id="'.$tag.'">'."\n"; + $this->stringtoshow.='$(function () {'."\n"; $i=$firstlot; while ($i < $nblot) { - $this->_stringtoshow.=$serie[$i]; + $this->stringtoshow.=$serie[$i]; $i++; } - $this->_stringtoshow.="\n"; + $this->stringtoshow.="\n"; // Special case for Graph of type 'pie' if (isset($this->type[$firstlot]) && $this->type[$firstlot] == 'pie') @@ -871,7 +871,7 @@ class DolGraph $showpointvalue=$this->showpointvalue; $showpercent=$this->showpercent; - $this->_stringtoshow.= ' + $this->stringtoshow.= ' function plotWithOptions_'.$tag.'() { $.plot($("#placeholder_'.$tag.'"), d0, { @@ -886,15 +886,15 @@ class DolGraph var percent=Math.round(series.percent); var number=series.data[0][1]; return \''; - $this->_stringtoshow.='<div style="font-size:8pt;text-align:center;padding:2px;color:white;">'; - if ($urltemp) $this->_stringtoshow.='<a style="color: #FFFFFF;" border="0" href="'.$urltemp.'">'; - $this->_stringtoshow.='\'+'; - $this->_stringtoshow.=($showlegend?'':'label+\'<br/>\'+'); // Hide label if already shown in legend - $this->_stringtoshow.=($showpointvalue?'number+':''); - $this->_stringtoshow.=($showpercent?'\'<br/>\'+percent+\'%\'+':''); - $this->_stringtoshow.='\''; - if ($urltemp) $this->_stringtoshow.='</a>'; - $this->_stringtoshow.='</div>\'; + $this->stringtoshow.='<div style="font-size:8pt;text-align:center;padding:2px;color:white;">'; + if ($urltemp) $this->stringtoshow.='<a style="color: #FFFFFF;" border="0" href="'.$urltemp.'">'; + $this->stringtoshow.='\'+'; + $this->stringtoshow.=($showlegend?'':'label+\'<br/>\'+'); // Hide label if already shown in legend + $this->stringtoshow.=($showpointvalue?'number+':''); + $this->stringtoshow.=($showpercent?'\'<br/>\'+percent+\'%\'+':''); + $this->stringtoshow.='\''; + if ($urltemp) $this->stringtoshow.='</a>'; + $this->stringtoshow.='</div>\'; }, background: { opacity: 0.5, @@ -911,9 +911,9 @@ class DolGraph },'; if (count($datacolor)) { - $this->_stringtoshow.='colors: '.(! empty($data['seriescolor']) ? json_encode($data['seriescolor']) : json_encode($datacolor)).','; + $this->stringtoshow.='colors: '.(! empty($data['seriescolor']) ? json_encode($data['seriescolor']) : json_encode($datacolor)).','; } - $this->_stringtoshow.='legend: {show: '.($showlegend?'true':'false').', position: \'ne\' } + $this->stringtoshow.='legend: {show: '.($showlegend?'true':'false').', position: \'ne\' } }); }'."\n"; } @@ -921,7 +921,7 @@ class DolGraph else { // Add code to support tooltips - $this->_stringtoshow.=' + $this->stringtoshow.=' function showTooltip_'.$tag.'(x, y, contents) { $(\'<div id="tooltip_'.$tag.'">\' + contents + \'</div>\').css({ position: \'absolute\', @@ -935,26 +935,26 @@ class DolGraph opacity: 0.80 }).appendTo("body").fadeIn(20); } - + var previousPoint = null; $("#placeholder_'.$tag.'").bind("plothover", function (event, pos, item) { $("#x").text(pos.x.toFixed(2)); $("#y").text(pos.y.toFixed(2)); - + if (item) { if (previousPoint != item.dataIndex) { previousPoint = item.dataIndex; - + $("#tooltip").remove(); /* console.log(item); */ var x = item.datapoint[0].toFixed(2); var y = item.datapoint[1].toFixed(2); var z = item.series.xaxis.ticks[item.dataIndex].label; '; - if ($this->showpointvalue > 0) $this->_stringtoshow.=' + if ($this->showpointvalue > 0) $this->stringtoshow.=' showTooltip_'.$tag.'(item.pageX, item.pageY, item.series.label + "<br>" + z + " => " + y); '; - $this->_stringtoshow.=' + $this->stringtoshow.=' } } else { @@ -964,50 +964,50 @@ class DolGraph }); '; - $this->_stringtoshow.='var stack = null, steps = false;'."\n"; + $this->stringtoshow.='var stack = null, steps = false;'."\n"; - $this->_stringtoshow.='function plotWithOptions_'.$tag.'() {'."\n"; - $this->_stringtoshow.='$.plot($("#placeholder_'.$tag.'"), [ '."\n"; + $this->stringtoshow.='function plotWithOptions_'.$tag.'() {'."\n"; + $this->stringtoshow.='$.plot($("#placeholder_'.$tag.'"), [ '."\n"; $i=$firstlot; while ($i < $nblot) { - if ($i > $firstlot) $this->_stringtoshow.=', '."\n"; + if ($i > $firstlot) $this->stringtoshow.=', '."\n"; $color=sprintf("%02x%02x%02x",$this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2]); - $this->_stringtoshow.='{ '; - if (! isset($this->type[$i]) || $this->type[$i] == 'bars') $this->_stringtoshow.='bars: { show: true, align: "'.($i==$firstlot?'center':'left').'", barWidth: 0.5 }, '; - if (isset($this->type[$i]) && $this->type[$i] == 'lines') $this->_stringtoshow.='lines: { show: true, fill: false }, '; - $this->_stringtoshow.='color: "#'.$color.'", label: "'.(isset($this->Legend[$i]) ? dol_escape_js($this->Legend[$i]) : '').'", data: d'.$i.' }'; + $this->stringtoshow.='{ '; + if (! isset($this->type[$i]) || $this->type[$i] == 'bars') $this->stringtoshow.='bars: { show: true, align: "'.($i==$firstlot?'center':'left').'", barWidth: 0.5 }, '; + if (isset($this->type[$i]) && $this->type[$i] == 'lines') $this->stringtoshow.='lines: { show: true, fill: false }, '; + $this->stringtoshow.='color: "#'.$color.'", label: "'.(isset($this->Legend[$i]) ? dol_escape_js($this->Legend[$i]) : '').'", data: d'.$i.' }'; $i++; } - $this->_stringtoshow.="\n".' ], { series: { stack: stack, lines: { fill: false, steps: steps }, bars: { barWidth: 0.6 } }'."\n"; + $this->stringtoshow.="\n".' ], { series: { stack: stack, lines: { fill: false, steps: steps }, bars: { barWidth: 0.6 } }'."\n"; // Xaxis - $this->_stringtoshow.=', xaxis: { ticks: ['."\n"; + $this->stringtoshow.=', xaxis: { ticks: ['."\n"; $x=0; foreach($this->data as $key => $valarray) { - if ($x > 0) $this->_stringtoshow.=', '."\n"; - $this->_stringtoshow.= ' ['.$x.', "'.$valarray[0].'"]'; + if ($x > 0) $this->stringtoshow.=', '."\n"; + $this->stringtoshow.= ' ['.$x.', "'.$valarray[0].'"]'; $x++; } - $this->_stringtoshow.='] }'."\n"; + $this->stringtoshow.='] }'."\n"; // Yaxis - $this->_stringtoshow.=', yaxis: { min: '.$this->MinValue.', max: '.($this->MaxValue).' }'."\n"; + $this->stringtoshow.=', yaxis: { min: '.$this->MinValue.', max: '.($this->MaxValue).' }'."\n"; // Background color $color1=sprintf("%02x%02x%02x",$this->bgcolorgrid[0],$this->bgcolorgrid[0],$this->bgcolorgrid[2]); $color2=sprintf("%02x%02x%02x",$this->bgcolorgrid[0],$this->bgcolorgrid[1],$this->bgcolorgrid[2]); - $this->_stringtoshow.=', grid: { hoverable: true, backgroundColor: { colors: ["#'.$color1.'", "#'.$color2.'"] } }'."\n"; - //$this->_stringtoshow.=', shadowSize: 20'."\n"; TODO Uncommet this - $this->_stringtoshow.='});'."\n"; - $this->_stringtoshow.='}'."\n"; + $this->stringtoshow.=', grid: { hoverable: true, backgroundColor: { colors: ["#'.$color1.'", "#'.$color2.'"] } }'."\n"; + //$this->stringtoshow.=', shadowSize: 20'."\n"; TODO Uncommet this + $this->stringtoshow.='});'."\n"; + $this->stringtoshow.='}'."\n"; } - $this->_stringtoshow.='plotWithOptions_'.$tag.'();'."\n"; - $this->_stringtoshow.='});'."\n"; - $this->_stringtoshow.='</script>'."\n"; + $this->stringtoshow.='plotWithOptions_'.$tag.'();'."\n"; + $this->stringtoshow.='});'."\n"; + $this->stringtoshow.='</script>'."\n"; } @@ -1019,10 +1019,10 @@ class DolGraph */ function show() { - return $this->_stringtoshow; + return $this->stringtoshow; } - + /** * getDefaultGraphSizeForStats * @@ -1033,18 +1033,18 @@ class DolGraph static function getDefaultGraphSizeForStats($direction,$defaultsize='') { global $conf; - + if ($direction == 'width') { if (empty($conf->dol_optimize_smallscreen)) return ($defaultsize ? $defaultsize : '500'); else return (empty($_SESSION['dol_screen_width']) ? '280' : ($_SESSION['dol_screen_width']-40)); } - if ($direction == 'height') + if ($direction == 'height') { return (empty($conf->dol_optimize_smallscreen)?($defaultsize?$defaultsize:'200'):'160'); } return 0; } - + } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index e7cc87efef5e793a2809a70993ef6a8d61b2ce48..24d8c40f5b353c2c9edbd8c38f28ba14e5d7006f 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -54,7 +54,9 @@ class ExtraFields var $attribute_alwayseditable; // Array to store permission to check var $attribute_perms; - + // Array to store permission to check + var $attribute_list; + var $error; var $errno; @@ -93,6 +95,7 @@ class ExtraFields $this->attribute_unique = array(); $this->attribute_required = array(); $this->attribute_perms = array(); + $this->attribute_list = array(); } /** @@ -110,9 +113,10 @@ class ExtraFields * @param array $param Params for field * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check + * @param int $list Into list view by default * @return int <=0 if KO, >0 if OK */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param=0, $alwayseditable=0, $perms='') + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param=0, $alwayseditable=0, $perms='', $list=0) { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -122,13 +126,13 @@ class ExtraFields // Create field into database except for separator type which is not stored in database if ($type != 'separate') { - $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param); + $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value, $param, $perms, $list); } $err1=$this->errno; if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param, $alwayseditable, $perms); + $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param, $alwayseditable, $perms, $list); $err2=$this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { @@ -156,10 +160,11 @@ class ExtraFields * @param int $required Is field required or not * @param string $default_value Default value for field * @param array $param Params for field (ex for select list : array('options'=>array('value'=>'label of option')) - * + * @param string $perms Permission + * @param int $list Into list view by default * @return int <=0 if KO, >0 if OK */ - private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='') + private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='', $perms='', $list=0) { if ($elementtype == 'thirdparty') $elementtype='societe'; @@ -230,9 +235,10 @@ class ExtraFields * @param array||string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check + * @param int $list Into list view by default * @return int <=0 if KO, >0 if OK */ - private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='') + private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=0) { global $conf; @@ -240,6 +246,7 @@ class ExtraFields // Clean parameters if (empty($pos)) $pos=0; + if (empty($list)) $list=0; if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname) && ! is_numeric($attrname)) { @@ -256,7 +263,7 @@ class ExtraFields $params=''; } - $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param, alwayseditable, perms)"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param, alwayseditable, perms, list)"; $sql.= " VALUES('".$attrname."',"; $sql.= " '".$this->db->escape($label)."',"; $sql.= " '".$type."',"; @@ -267,8 +274,9 @@ class ExtraFields $sql.= " '".$unique."',"; $sql.= " '".$required."',"; $sql.= " '".$params."',"; - $sql.= " '".$alwayseditable."'"; - $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null"); + $sql.= " '".$alwayseditable."',"; + $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").","; + $sql.= " ".$list; $sql.=')'; dol_syslog(get_class($this)."::create_label", LOG_DEBUG); @@ -370,9 +378,10 @@ class ExtraFields * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check + * @param int $list Into list view by default * @return int >0 if OK, <=0 if KO */ - function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0, $perms='') + function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0, $perms='',$list='') { if ($elementtype == 'thirdparty') $elementtype='societe'; @@ -409,7 +418,7 @@ class ExtraFields { if ($label) { - $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms); + $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list); } if ($result > 0) { @@ -459,14 +468,17 @@ class ExtraFields * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check + * @param int $list Into list view by default * @return int <=0 if KO, >0 if OK */ - private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='') + private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0) { global $conf; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list); + // Clean parameters if ($elementtype == 'thirdparty') $elementtype='societe'; + if (empty($list)) $list=0; if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { @@ -496,7 +508,8 @@ class ExtraFields $sql.= " perms,"; $sql.= " pos,"; $sql.= " alwayseditable,"; - $sql.= " param"; + $sql.= " param,"; + $sql.= " list"; $sql.= ") VALUES ("; $sql.= "'".$attrname."',"; $sql.= " ".$conf->entity.","; @@ -506,10 +519,11 @@ class ExtraFields $sql.= " '".$elementtype."',"; $sql.= " '".$unique."',"; $sql.= " '".$required."',"; - $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null"); + $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").","; $sql.= " '".$pos."',"; $sql.= " '".$alwayseditable."',"; $sql.= " '".$param."'"; + $sql.= " ".$list; $sql.= ")"; dol_syslog(get_class($this)."::update_label", LOG_DEBUG); $resql2=$this->db->query($sql); @@ -552,7 +566,7 @@ class ExtraFields // For avoid conflicts with external modules if (!$forceload && !empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return $array_name_label; - $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms"; + $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,list"; $sql.= " FROM ".MAIN_DB_PREFIX."extrafields"; $sql.= " WHERE entity IN (0,".$conf->entity.")"; if ($elementtype) $sql.= " AND elementtype = '".$elementtype."'"; @@ -582,6 +596,7 @@ class ExtraFields $this->attribute_pos[$tab->name]=$tab->pos; $this->attribute_alwayseditable[$tab->name]=$tab->alwayseditable; $this->attribute_perms[$tab->name]=$tab->perms; + $this->attribute_perms[$tab->name]=$tab->list; } } } @@ -615,6 +630,8 @@ class ExtraFields $required=$this->attribute_required[$key]; $param=$this->attribute_param[$key]; $perms=$this->attribute_perms[$key]; + $list=$this->attribute_list[$key]; + if ($type == 'date') { $showsize=10; @@ -895,7 +912,7 @@ class ExtraFields elseif ($type == 'chkbxlst') { $value_arr = explode(',', $value); - + if (is_array($param['options'])) { $param_list = array_keys($param['options']); $InfoFieldList = explode(":", $param_list[0]); @@ -905,7 +922,7 @@ class ExtraFields // 3 : key field parent (for dependent lists) // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid'); - + if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3])) { list ( $parentName, $parentField ) = explode('|', $InfoFieldList[3]); $keyList .= ', ' . $parentField; @@ -917,13 +934,13 @@ class ExtraFields $keyList = $InfoFieldList[2] . ' as rowid'; } } - + $fields_label = explode('|', $InfoFieldList[1]); if (is_array($fields_label)) { $keyList .= ', '; $keyList .= implode(', ', $fields_label); } - + $sqlwhere = ''; $sql = 'SELECT ' . $keyList; $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0]; @@ -939,7 +956,7 @@ class ExtraFields $sqlwhere .= ' WHERE 1'; } if (in_array($InfoFieldList[0], array ( - 'tablewithentity' + 'tablewithentity' ))) $sqlwhere .= ' AND entity = ' . $conf->entity; // Some tables may have field, some other not. For the moment we disable it. // $sql.=preg_replace('/^ AND /','',$sqlwhere); @@ -953,7 +970,7 @@ class ExtraFields while ( $i < $num ) { $labeltoshow = ''; $obj = $this->db->fetch_object($resql); - + // Several field into label (eq table:code|libelle:rowid) $fields_label = explode('|', $InfoFieldList[1]); if (is_array($fields_label)) { @@ -965,7 +982,7 @@ class ExtraFields $labeltoshow = $obj->$InfoFieldList[1]; } $labeltoshow = dol_trunc($labeltoshow, 45); - + if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { foreach ( $fields_label as $field_toshow ) { $translabel = $langs->trans($obj->$field_toshow); @@ -977,9 +994,9 @@ class ExtraFields } $out .= '<input class="flat" type="checkbox" name="options_' . $key . $keyprefix . '[]" ' . ($moreparam ? $moreparam : ''); $out .= ' value="' . $obj->rowid . '"'; - + $out .= 'checked="checked"'; - + $out .= '/>' . $labeltoshow . '<br>'; } else { if (! $notrans) { @@ -992,31 +1009,31 @@ class ExtraFields } if (empty($labeltoshow)) $labeltoshow = '(not defined)'; - + if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { $out .= '<input class="flat" type="checkbox" name="options_' . $key . $keyprefix . '[]" ' . ($moreparam ? $moreparam : ''); $out .= ' value="' . $obj->rowid . '"'; - + $out .= 'checked="checked"'; $out .= ''; - + $out .= '/>' . $labeltoshow . '<br>'; } - + if (! empty($InfoFieldList[3])) { $parent = $parentName . ':' . $obj->{$parentField}; } - + $out .= '<input class="flat" type="checkbox" name="options_' . $key . $keyprefix . '[]" ' . ($moreparam ? $moreparam : ''); $out .= ' value="' . $obj->rowid . '"'; - + $out .= ((is_array($value_arr) && in_array($obj->rowid, $value_arr)) ? ' checked="checked" ' : ''); ; $out .= ''; - + $out .= '/>' . $labeltoshow . '<br>'; } - + $i ++; } $this->db->free($resql); @@ -1053,6 +1070,8 @@ class ExtraFields $required=$this->attribute_required[$key]; $params=$this->attribute_param[$key]; $perms=$this->attribute_perms[$key]; + $list=$this->attribute_list[$key]; + if ($type == 'date') { $showsize=10; @@ -1185,24 +1204,24 @@ class ExtraFields elseif ($type == 'chkbxlst') { $value_arr = explode(',', $value); - + $param_list = array_keys($params['options']); $InfoFieldList = explode(":", $param_list[0]); - + $selectkey = "rowid"; $keyList = 'rowid'; - + if (count($InfoFieldList) >= 3) { $selectkey = $InfoFieldList[2]; $keyList = $InfoFieldList[2] . ' as rowid'; } - + $fields_label = explode('|', $InfoFieldList[1]); if (is_array($fields_label)) { $keyList .= ', '; $keyList .= implode(', ', $fields_label); } - + $sql = 'SELECT ' . $keyList; $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0]; if (strpos($InfoFieldList[4], 'extra') !== false) { @@ -1210,14 +1229,14 @@ class ExtraFields } // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'"; // $sql.= ' AND entity = '.$conf->entity; - + dol_syslog(get_class($this) . ':showOutputField:$type=chkbxlst',LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $value = ''; // value was used, so now we reste it to use it to build final output - + while ( $obj = $this->db->fetch_object($resql) ) { - + // Several field into label (eq table:code|libelle:rowid) $fields_label = explode('|', $InfoFieldList[1]); if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 94f1568c5a2cd23432ac843adf7f10fef4e25771..c7177475a340ca28497401c5739ee6c5972faca7 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -275,6 +275,7 @@ abstract class DoliDB implements Database */ function jdate($string, $gm=false) { + if ($string==0 || $string=="0000-00-00 00:00:00") return ''; $string=preg_replace('/([^0-9])/i','',$string); $tmp=$string.'000000'; $date=dol_mktime(substr($tmp,8,2),substr($tmp,10,2),substr($tmp,12,2),substr($tmp,4,2),substr($tmp,6,2),substr($tmp,0,4),$gm); diff --git a/htdocs/core/db/sqlite.class.php b/htdocs/core/db/sqlite.class.php index b16114a773f974024469c8fc974ce1377b0402dd..88efde86394cb375db069b8e1f821efb7536b466 100644 --- a/htdocs/core/db/sqlite.class.php +++ b/htdocs/core/db/sqlite.class.php @@ -50,6 +50,7 @@ class DoliDBSqlite extends DoliDB * @param string $pass Mot de passe * @param string $name Nom de la database * @param int $port Port of database server + * @return int 1 if OK, 0 if not */ function __construct($type, $host, $user, $pass, $name='', $port=0) { diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php new file mode 100644 index 0000000000000000000000000000000000000000..3c95d9f73f7e05cfc5db435656c033f9c9010f62 --- /dev/null +++ b/htdocs/core/db/sqlite3.class.php @@ -0,0 +1,1532 @@ +<?php +/* Copyright (C) 2001 Fabien Seisen <seisen@linuxfr.org> + * Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr> + * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@capnetworks.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/core/db/sqlite.class.php + * \brief Class file to manage Dolibarr database access for a Sqlite database + */ + +require_once DOL_DOCUMENT_ROOT .'/core/db/DoliDB.class.php'; + +/** + * Class to manage Dolibarr database access for a Sqlite database + */ +class DoliDBSqlite3 extends DoliDB +{ + //! Database type + public $type='sqlite3'; + //! Database label + const LABEL='Sqlite3'; + //! Version min database + const VERSIONMIN='3.0.0'; + //! Resultset of last query + private $_results; + + const WEEK_MONDAY_FIRST=1; + const WEEK_YEAR = 2; + const WEEK_FIRST_WEEKDAY=4; + + + /** + * Constructor. + * This create an opened connexion to a database server and eventually to a database + * + * @param string $type Type of database (mysql, pgsql...) + * @param string $host Address of database server + * @param string $user Nom de l'utilisateur autorise + * @param string $pass Mot de passe + * @param string $name Nom de la database + * @param int $port Port of database server + */ + function __construct($type, $host, $user, $pass, $name='', $port=0) + { + global $conf,$langs; + + // Note that having "static" property for "$forcecharset" and "$forcecollate" will make error here in strict mode, so they are not static + if (! empty($conf->db->character_set)) $this->forcecharset=$conf->db->character_set; + if (! empty($conf->db->dolibarr_main_db_collation)) $this->forcecollate=$conf->db->dolibarr_main_db_collation; + + $this->database_user=$user; + $this->database_host=$host; + $this->database_port=$port; + + $this->transaction_opened=0; + + //print "Name DB: $host,$user,$pass,$name<br>"; + + /*if (! function_exists("sqlite_query")) + { + $this->connected = 0; + $this->ok = 0; + $this->error="Sqlite PHP functions for using Sqlite driver are not available in this version of PHP. Try to use another driver."; + dol_syslog(get_class($this)."::DoliDBSqlite3 : Sqlite PHP functions for using Sqlite driver are not available in this version of PHP. Try to use another driver.",LOG_ERR); + return $this->ok; + }*/ + + /*if (! $host) + { + $this->connected = 0; + $this->ok = 0; + $this->error=$langs->trans("ErrorWrongHostParameter"); + dol_syslog(get_class($this)."::DoliDBSqlite3 : Erreur Connect, wrong host parameters",LOG_ERR); + return $this->ok; + }*/ + + // Essai connexion serveur + // We do not try to connect to database, only to server. Connect to database is done later in constrcutor + $this->db = $this->connect($host, $user, $pass, $name, $port); + + if ($this->db) + { + $this->connected = 1; + $this->ok = 1; + $this->database_selected = 1; + $this->database_name = $name; + + $this->addCustomFunction('IF'); + $this->addCustomFunction('MONTH'); + $this->addCustomFunction('CURTIME'); + $this->addCustomFunction('CURDATE'); + $this->addCustomFunction('WEEK', 1); + $this->addCustomFunction('WEEK', 2); + $this->addCustomFunction('WEEKDAY'); + $this->addCustomFunction('date_format'); + //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } + else + { + // host, login ou password incorrect + $this->connected = 0; + $this->ok = 0; + $this->database_selected = 0; + $this->database_name = ''; + //$this->error=sqlite_connect_error(); + dol_syslog(get_class($this)."::DoliDBSqlite3 : Error Connect ".$this->error,LOG_ERR); + } + + return $this->ok; + } + + + /** + * Convert a SQL request in Mysql syntax to native syntax + * + * @param string $line SQL request line to convert + * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) + * @return string SQL request line converted + */ + static function convertSQLFromMysql($line,$type='ddl') + { + // Removed empty line if this is a comment line for SVN tagging + if (preg_match('/^--\s\$Id/i',$line)) { + return ''; + } + // Return line if this is a comment + if (preg_match('/^#/i',$line) || preg_match('/^$/i',$line) || preg_match('/^--/i',$line)) + { + return $line; + } + if ($line != "") + { + if ($type == 'auto') + { + if (preg_match('/ALTER TABLE/i',$line)) $type='dml'; + else if (preg_match('/CREATE TABLE/i',$line)) $type='dml'; + else if (preg_match('/DROP TABLE/i',$line)) $type='dml'; + } + + if ($type == 'dml') + { + $line=preg_replace('/\s/',' ',$line); // Replace tabulation with space + + // we are inside create table statement so lets process datatypes + if (preg_match('/(ISAM|innodb)/i',$line)) { // end of create table sequence + $line=preg_replace('/\)[\s\t]*type[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line); + $line=preg_replace('/\)[\s\t]*engine[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line); + $line=preg_replace('/,$/','',$line); + } + + // Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..." + if (preg_match('/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i',$line,$reg)) { + $newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 integer PRIMARY KEY AUTOINCREMENT',$line); + //$line = "-- ".$line." replaced by --\n".$newline; + $line=$newline; + } + + // tinyint type conversion + $line=str_replace('tinyint','smallint',$line); + + // nuke unsigned + $line=preg_replace('/(int\w+|smallint)\s+unsigned/i','\\1',$line); + + // blob -> text + $line=preg_replace('/\w*blob/i','text',$line); + + // tinytext/mediumtext -> text + $line=preg_replace('/tinytext/i','text',$line); + $line=preg_replace('/mediumtext/i','text',$line); + + // change not null datetime field to null valid ones + // (to support remapping of "zero time" to null + $line=preg_replace('/datetime not null/i','datetime',$line); + $line=preg_replace('/datetime/i','timestamp',$line); + + // double -> numeric + $line=preg_replace('/^double/i','numeric',$line); + $line=preg_replace('/(\s*)double/i','\\1numeric',$line); + // float -> numeric + $line=preg_replace('/^float/i','numeric',$line); + $line=preg_replace('/(\s*)float/i','\\1numeric',$line); + + // unique index(field1,field2) + if (preg_match('/unique index\s*\((\w+\s*,\s*\w+)\)/i',$line)) + { + $line=preg_replace('/unique index\s*\((\w+\s*,\s*\w+)\)/i','UNIQUE\(\\1\)',$line); + } + + // We remove end of requests "AFTER fieldxxx" + $line=preg_replace('/AFTER [a-z0-9_]+/i','',$line); + + // We remove start of requests "ALTER TABLE tablexxx" if this is a DROP INDEX + $line=preg_replace('/ALTER TABLE [a-z0-9_]+ DROP INDEX/i','DROP INDEX',$line); + + // Translate order to rename fields + if (preg_match('/ALTER TABLE ([a-z0-9_]+) CHANGE(?: COLUMN)? ([a-z0-9_]+) ([a-z0-9_]+)(.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $line.= "ALTER TABLE ".$reg[1]." RENAME COLUMN ".$reg[2]." TO ".$reg[3]; + } + + // Translate order to modify field format + if (preg_match('/ALTER TABLE ([a-z0-9_]+) MODIFY(?: COLUMN)? ([a-z0-9_]+) (.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $newreg3=$reg[3]; + $newreg3=preg_replace('/ DEFAULT NULL/i','',$newreg3); + $newreg3=preg_replace('/ NOT NULL/i','',$newreg3); + $newreg3=preg_replace('/ NULL/i','',$newreg3); + $newreg3=preg_replace('/ DEFAULT 0/i','',$newreg3); + $newreg3=preg_replace('/ DEFAULT \'[0-9a-zA-Z_@]*\'/i','',$newreg3); + $line.= "ALTER TABLE ".$reg[1]." ALTER COLUMN ".$reg[2]." TYPE ".$newreg3; + // TODO Add alter to set default value or null/not null if there is this in $reg[3] + } + + // alter table add primary key (field1, field2 ...) -> We create a unique index instead as dynamic creation of primary key is not supported + // ALTER TABLE llx_dolibarr_modules ADD PRIMARY KEY pk_dolibarr_modules (numero, entity); + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $line.= "CREATE UNIQUE INDEX ".$reg[2]." ON ".$reg[1]."(".$reg[3]; + } + + // Translate order to drop foreign keys + // ALTER TABLE llx_dolibarr_modules DROP FOREIGN KEY fk_xxx; + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*DROP\s+FOREIGN\s+KEY\s*(.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $line.= "ALTER TABLE ".$reg[1]." DROP CONSTRAINT ".$reg[2]; + } + + // alter table add [unique] [index] (field1, field2 ...) + // ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version) + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+(UNIQUE INDEX|INDEX|UNIQUE)\s+(.*)\s*\(([\w,\s]+)\)/i',$line,$reg)) + { + $fieldlist=$reg[4]; + $idxname=$reg[3]; + $tablename=$reg[1]; + $line = "-- ".$line." replaced by --\n"; + $line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")"; + } + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$line, $reg)) { + // Pour l'instant les contraintes ne sont pas créées + dol_syslog(get_class().'::query line emptied'); + $line = 'SELECT 0;'; + + } + + //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) { + //preg_replace('/(rowid\s+.*\s+PRIMARY\s+KEY\s*,)/i', '/* \\1 */', $line); + //} + } + + // Delete using criteria on other table must not declare twice the deleted table + // DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable + if (preg_match('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i',$line,$reg)) + { + if ($reg[1] == $reg[2]) // If same table, we remove second one + { + $line=preg_replace('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i','DELETE FROM \\1 USING \\3', $line); + } + } + + // Remove () in the tables in FROM if one table + $line=preg_replace('/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i','FROM \\1',$line); + //print $line."\n"; + + // Remove () in the tables in FROM if two table + $line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2',$line); + //print $line."\n"; + + // Remove () in the tables in FROM if two table + $line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2, \\3',$line); + //print $line."\n"; + + //print "type=".$type." newline=".$line."<br>\n"; + } + + return $line; + } + + /** + * Select a database + * + * @param string $database Name of database + * @return boolean true if OK, false if KO + */ + function select_db($database) + { + dol_syslog(get_class($this)."::select_db database=".$database, LOG_DEBUG); + return sqlite_select_db($this->db,$database); + } + + + /** + * Connexion to server + * + * @param string $host database server host + * @param string $login login + * @param string $passwd password + * @param string $name name of database (not used for mysql, used for pgsql) + * @param string $port Port of database server + * @return resource Database access handler + * @see close + */ + function connect($host, $login, $passwd, $name, $port=0) + { + global $conf,$main_data_dir; + + dol_syslog(get_class($this)."::connect name=".$name,LOG_DEBUG); + + $dir=$main_data_dir; + if (empty($dir)) $dir=DOL_DATA_ROOT; + // With sqlite, port must be in connect parameters + //if (! $newport) $newport=3306; + $database_name = $dir.'/database_'.$name.'.sdb'; + try { + /*** connect to SQLite database ***/ + //$this->db = new PDO("sqlite:".$dir.'/database_'.$name.'.sdb'); + $this->db = new SQLite3($database_name); + //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } + catch(Exception $e) + { + $this->error= self::LABEL.' '.$e->getMessage().' current dir='.$database_name; + return ''; + } + + //print "Resultat fonction connect: ".$this->db; + return $this->db; + } + + + /** + * Return version of database server + * + * @return string Version string + */ + function getVersion() + { + $tmp=$this->db->version(); + return $tmp['versionString']; + } + + /** + * Return version of database client driver + * + * @return string Version string + */ + function getDriverInfo() + { + // FIXME: Dummy method + // TODO: Implement + + return ''; + } + + + /** + * Close database connexion + * + * @return boolean True if disconnect successfull, false otherwise + * @see connect + */ + function close() + { + if ($this->db) + { + if ($this->transaction_opened > 0) dol_syslog(get_class($this)."::close Closing a connection with an opened transaction depth=".$this->transaction_opened,LOG_ERR); + $this->connected=0; + $this->db->close(); + $this->db=null; // Clean this->db + return true; + } + return false; + } + + /** + * Execute a SQL request and return the resultset + * + * @param string $query SQL query string + * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollbock to savepoint if error (this allow to have some request with errors inside global transactions). + * Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints. + * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) + * @return resource Resultset of answer + */ + function query($query,$usesavepoint=0,$type='auto') + { + $errmsg=''; + + $ret=''; + $query = trim($query); + $this->error = 0; + + // Convert MySQL syntax to SQLite syntax + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$query, $reg)) { + // Ajout d'une clef étrangère à la table + // procédure de remplacement de la table pour ajouter la contrainte + // Exemple : ALTER TABLE llx_adherent ADD CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid) + // -> CREATE TABLE ( ... ,CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid)) + $foreignFields = $reg[5]; + $foreignTable = $reg[4]; + $localfields = $reg[3]; + $constraintname=trim($reg[2]); + $tablename=trim($reg[1]); + + $descTable = $this->db->querySingle("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'"); + + // 1- Renommer la table avec un nom temporaire + $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename); + + // 2- Recréer la table avec la contrainte ajoutée + + // on bricole la requete pour ajouter la contrainte + $descTable = substr($descTable, 0, strlen($descTable) - 1); + $descTable .= ", CONSTRAINT " . $constraintname . " FOREIGN KEY (" . $localfields . ") REFERENCES " .$foreignTable . "(" . $foreignFields . ")"; + + // fermeture de l'instruction + $descTable .= ')'; + + // Création proprement dite de la table + $this->query($descTable); + + // 3- Transférer les données + $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename); + + // 4- Supprimer la table temporaire + $this->query('DROP TABLE tmp_' . $tablename); + + // dummy statement + $query="SELECT 0"; + + } else { + $query=$this->convertSQLFromMysql($query,$type); + } + //print "After convertSQLFromMysql:\n".$query."<br>\n"; + + dol_syslog('sql='.$query, LOG_DEBUG); + + // Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE) + try { + //$ret = $this->db->exec($query); + $ret = $this->db->query($query); // $ret is a Sqlite3Result + if ($ret) { + $ret->queryString = $query; + } + } + catch(Exception $e) + { + $this->error=$this->db->lastErrorMsg(); + } + + if (! preg_match("/^COMMIT/i",$query) && ! preg_match("/^ROLLBACK/i",$query)) + { + // Si requete utilisateur, on la sauvegarde ainsi que son resultset + if (! is_object($ret) || $this->error) + { + $this->lastqueryerror = $query; + $this->lasterror = $this->error(); + $this->lasterrno = $this->errno(); + + dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); + + $errormsg = get_class($this)."::query SQL Error message: ".$this->lasterror; + + if (preg_match('/[0-9]/',$this->lasterrno)) { + $errormsg .= ' ('.$this->lasterrno.')'; + } + + dol_syslog($errormsg, LOG_ERR); + } + $this->lastquery=$query; + $this->_results = $ret; + } + + return $ret; + } + + /** + * Renvoie la ligne courante (comme un objet) pour le curseur resultset + * + * @param Resultset $resultset Curseur de la requete voulue + * @return Object Object result line or false if KO or end of cursor + */ + function fetch_object($resultset) + { + // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + //return $resultset->fetch(PDO::FETCH_OBJ); + $ret = $resultset->fetchArray(SQLITE3_ASSOC); + if ($ret) { + return (object) $ret; + } + } + + + /** + * Return datas as an array + * + * @param Resultset $resultset Resultset of request + * @return array Array + */ + function fetch_array($resultset) + { + // If resultset not provided, we take the last used by connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + //return $resultset->fetch(PDO::FETCH_ASSOC); + $ret = $resultset->fetchArray(SQLITE3_ASSOC); + if ($ret) { + return (array) $ret; + } + } + + /** + * Return datas as an array + * + * @param Resultset $resultset Resultset of request + * @return array Array + */ + function fetch_row($resultset) + { + // If resultset not provided, we take the last used by connexion + if (! is_bool($resultset)) + { + if (! is_object($resultset)) { $resultset=$this->_results; } + return $resultset->fetchArray(SQLITE3_NUM); + } + else + { + // si le curseur est un booleen on retourne la valeur 0 + return 0; + } + } + + /** + * Return number of lines for result of a SELECT + * + * @param Resultset $resultset Resulset of requests + * @return int Nb of lines + * @see affected_rows + */ + function num_rows($resultset) + { + // If resultset not provided, we take the last used by connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + if (preg_match("/^SELECT/i", $resultset->queryString)) { + return $this->db->querySingle("SELECT count(*) FROM (" . $resultset->queryString . ") q"); + } + return 0; + } + + /** + * Return number of lines for result of a SELECT + * + * @param Resultset $resultset Resulset of requests + * @return int Nb of lines + * @see affected_rows + */ + function affected_rows($resultset) + { + // If resultset not provided, we take the last used by connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + if (preg_match("/^SELECT/i", $resultset->queryString)) { + return $this->num_rows($resultset); + } + // mysql necessite un link de base pour cette fonction contrairement + // a pqsql qui prend un resultset + return $this->db->changes(); + } + + + /** + * Free last resultset used. + * + * @param resultset $resultset Curseur de la requete voulue + * @return void + */ + function free($resultset=0) + { + // If resultset not provided, we take the last used by connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + // Si resultset en est un, on libere la memoire + if ($resultset && is_object($resultset)) $resultset->finalize(); + } + + /** + * Escape a string to insert data + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + function escape($stringtoencode) + { + return Sqlite3::escapeString($stringtoencode); + } + + /** + * Renvoie le code erreur generique de l'operation precedente. + * + * @return string Error code (Exemples: DB_ERROR_TABLE_ALREADY_EXISTS, DB_ERROR_RECORD_ALREADY_EXISTS...) + */ + function errno() + { + if (! $this->connected) { + // Si il y a eu echec de connexion, $this->db n'est pas valide. + return 'DB_ERROR_FAILED_TO_CONNECT'; + } + else { + // Constants to convert error code to a generic Dolibarr error code + /*$errorcode_map = array( + 1004 => 'DB_ERROR_CANNOT_CREATE', + 1005 => 'DB_ERROR_CANNOT_CREATE', + 1006 => 'DB_ERROR_CANNOT_CREATE', + 1007 => 'DB_ERROR_ALREADY_EXISTS', + 1008 => 'DB_ERROR_CANNOT_DROP', + 1025 => 'DB_ERROR_NO_FOREIGN_KEY_TO_DROP', + 1044 => 'DB_ERROR_ACCESSDENIED', + 1046 => 'DB_ERROR_NODBSELECTED', + 1048 => 'DB_ERROR_CONSTRAINT', + 'HY000' => 'DB_ERROR_TABLE_ALREADY_EXISTS', + 1051 => 'DB_ERROR_NOSUCHTABLE', + 1054 => 'DB_ERROR_NOSUCHFIELD', + 1060 => 'DB_ERROR_COLUMN_ALREADY_EXISTS', + 1061 => 'DB_ERROR_KEY_NAME_ALREADY_EXISTS', + 1062 => 'DB_ERROR_RECORD_ALREADY_EXISTS', + 1064 => 'DB_ERROR_SYNTAX', + 1068 => 'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS', + 1075 => 'DB_ERROR_CANT_DROP_PRIMARY_KEY', + 1091 => 'DB_ERROR_NOSUCHFIELD', + 1100 => 'DB_ERROR_NOT_LOCKED', + 1136 => 'DB_ERROR_VALUE_COUNT_ON_ROW', + 1146 => 'DB_ERROR_NOSUCHTABLE', + 1216 => 'DB_ERROR_NO_PARENT', + 1217 => 'DB_ERROR_CHILD_EXISTS', + 1451 => 'DB_ERROR_CHILD_EXISTS' + ); + + if (isset($errorcode_map[$this->db->errorCode()])) + { + return $errorcode_map[$this->db->errorCode()]; + }*/ + $errno=$this->db->lastErrorCode(); + if ($errno=='HY000' || $errno == 0) + { + if (preg_match('/table.*already exists/i',$this->error)) return 'DB_ERROR_TABLE_ALREADY_EXISTS'; + elseif (preg_match('/index.*already exists/i',$this->error)) return 'DB_ERROR_KEY_NAME_ALREADY_EXISTS'; + elseif (preg_match('/syntax error/i',$this->error)) return 'DB_ERROR_SYNTAX'; + } + if ($errno=='23000') + { + if (preg_match('/column.* not unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS'; + elseif (preg_match('/PRIMARY KEY must be unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS'; + } + if ($errno > 1) { + // TODO Voir la liste des messages d'erreur + } + + return ($errno?'DB_ERROR_'.$errno:'0'); + } + } + + /** + * Renvoie le texte de l'erreur mysql de l'operation precedente. + * + * @return string Error text + */ + function error() + { + if (! $this->connected) { + // Si il y a eu echec de connexion, $this->db n'est pas valide pour sqlite_error. + return 'Not connected. Check setup parameters in conf/conf.php file and your sqlite version'; + } + else { + return $this->error; + } + } + + /** + * Get last ID after an insert INSERT + * + * @param string $tab Table name concerned by insert. Ne sert pas sous MySql mais requis pour compatibilite avec Postgresql + * @param string $fieldid Field name + * @return int Id of row + */ + function last_insert_id($tab,$fieldid='rowid') + { + return $this->db->lastInsertRowId(); + } + + /** + * Encrypt sensitive data in database + * Warning: This function includes the escape, so it must use direct value + * + * @param string $fieldorvalue Field name or value to encrypt + * @param int $withQuotes Return string with quotes + * @return return XXX(field) or XXX('value') or field or 'value' + */ + function encrypt($fieldorvalue, $withQuotes=0) + { + global $conf; + + // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption) + $cryptType = ($conf->db->dolibarr_main_db_encryption?$conf->db->dolibarr_main_db_encryption:0); + + //Encryption key + $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey)?$conf->db->dolibarr_main_db_cryptkey:''); + + $return = ($withQuotes?"'":"").$this->escape($fieldorvalue).($withQuotes?"'":""); + + if ($cryptType && !empty($cryptKey)) + { + if ($cryptType == 2) + { + $return = 'AES_ENCRYPT('.$return.',\''.$cryptKey.'\')'; + } + else if ($cryptType == 1) + { + $return = 'DES_ENCRYPT('.$return.',\''.$cryptKey.'\')'; + } + } + + return $return; + } + + /** + * Decrypt sensitive data in database + * + * @param string $value Value to decrypt + * @return string Decrypted value if used + */ + function decrypt($value) + { + global $conf; + + // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption) + $cryptType = ($conf->db->dolibarr_main_db_encryption?$conf->db->dolibarr_main_db_encryption:0); + + //Encryption key + $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey)?$conf->db->dolibarr_main_db_cryptkey:''); + + $return = $value; + + if ($cryptType && !empty($cryptKey)) + { + if ($cryptType == 2) + { + $return = 'AES_DECRYPT('.$value.',\''.$cryptKey.'\')'; + } + else if ($cryptType == 1) + { + $return = 'DES_DECRYPT('.$value.',\''.$cryptKey.'\')'; + } + } + + return $return; + } + + + /** + * Return connexion ID + * + * @return string Id connexion + */ + function DDLGetConnectId() + { + return '?'; + } + + + /** + * Create a new database + * Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated + * We force to create database with charset this->forcecharset and collate this->forcecollate + * + * @param string $database Database name to create + * @param string $charset Charset used to store data + * @param string $collation Charset used to sort data + * @param string $owner Username of database owner + * @return resource resource defined if OK, null if KO + */ + function DDLCreateDb($database,$charset='',$collation='',$owner='') + { + if (empty($charset)) $charset=$this->forcecharset; + if (empty($collation)) $collation=$this->forcecollate; + + // ALTER DATABASE dolibarr_db DEFAULT CHARACTER SET latin DEFAULT COLLATE latin1_swedish_ci + $sql = 'CREATE DATABASE '.$database; + $sql.= ' DEFAULT CHARACTER SET '.$charset.' DEFAULT COLLATE '.$collation; + + dol_syslog($sql,LOG_DEBUG); + $ret=$this->query($sql); + if (! $ret) + { + // We try again for compatibility with Mysql < 4.1.1 + $sql = 'CREATE DATABASE '.$database; + $ret=$this->query($sql); + dol_syslog($sql,LOG_DEBUG); + } + return $ret; + } + + /** + * List tables into a database + * + * @param string $database Name of database + * @param string $table Name of table filter ('xxx%') + * @return array List of tables in an array + */ + function DDLListTables($database, $table='') + { + $listtables=array(); + + $like = ''; + if ($table) $like = "LIKE '".$table."'"; + $sql="SHOW TABLES FROM ".$database." ".$like.";"; + //print $sql; + $result = $this->query($sql); + while($row = $this->fetch_row($result)) + { + $listtables[] = $row[0]; + } + return $listtables; + } + + /** + * List information of columns into a table. + * + * @param string $table Name of table + * @return array Tableau des informations des champs de la table + * TODO modify for sqlite + */ + function DDLInfoTable($table) + { + $infotables=array(); + + $sql="SHOW FULL COLUMNS FROM ".$table.";"; + + dol_syslog($sql,LOG_DEBUG); + $result = $this->query($sql); + while($row = $this->fetch_row($result)) + { + $infotables[] = $row; + } + return $infotables; + } + + /** + * Create a table into database + * + * @param string $table Nom de la table + * @param array $fields Tableau associatif [nom champ][tableau des descriptions] + * @param string $primary_key Nom du champ qui sera la clef primaire + * @param string $type Type de la table + * @param array $unique_keys Tableau associatifs Nom de champs qui seront clef unique => valeur + * @param array $fulltext_keys Tableau des Nom de champs qui seront indexes en fulltext + * @param string $keys Tableau des champs cles noms => valeur + * @return int <0 if KO, >=0 if OK + */ + function DDLCreateTable($table,$fields,$primary_key,$type,$unique_keys="",$fulltext_keys="",$keys="") + { + // cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra + // ex. : $fields['rowid'] = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment'); + $sql = "create table ".$table."("; + $i=0; + foreach($fields as $field_name => $field_desc) + { + $sqlfields[$i] = $field_name." "; + $sqlfields[$i] .= $field_desc['type']; + if( preg_match("/^[^\s]/i",$field_desc['value'])) + $sqlfields[$i] .= "(".$field_desc['value'].")"; + else if( preg_match("/^[^\s]/i",$field_desc['attribute'])) + $sqlfields[$i] .= " ".$field_desc['attribute']; + else if( preg_match("/^[^\s]/i",$field_desc['default'])) + { + if(preg_match("/null/i",$field_desc['default'])) + $sqlfields[$i] .= " default ".$field_desc['default']; + else + $sqlfields[$i] .= " default '".$field_desc['default']."'"; + } + else if( preg_match("/^[^\s]/i",$field_desc['null'])) + $sqlfields[$i] .= " ".$field_desc['null']; + + else if( preg_match("/^[^\s]/i",$field_desc['extra'])) + $sqlfields[$i] .= " ".$field_desc['extra']; + $i++; + } + if($primary_key != "") + $pk = "primary key(".$primary_key.")"; + + if($unique_keys != "") + { + $i = 0; + foreach($unique_keys as $key => $value) + { + $sqluq[$i] = "UNIQUE KEY '".$key."' ('".$value."')"; + $i++; + } + } + if($keys != "") + { + $i = 0; + foreach($keys as $key => $value) + { + $sqlk[$i] = "KEY ".$key." (".$value.")"; + $i++; + } + } + $sql .= implode(',',$sqlfields); + if($primary_key != "") + $sql .= ",".$pk; + if($unique_keys != "") + $sql .= ",".implode(',',$sqluq); + if($keys != "") + $sql .= ",".implode(',',$sqlk); + $sql .=") type=".$type; + + dol_syslog($sql,LOG_DEBUG); + if(! $this -> query($sql)) + return -1; + else + return 1; + } + + /** + * Return a pointer of line with description of a table or field + * + * @param string $table Name of table + * @param string $field Optionnel : Name of field if we want description of field + * @return resource Resource + */ + function DDLDescTable($table,$field="") + { + $sql="DESC ".$table." ".$field; + + dol_syslog(get_class($this)."::DDLDescTable ".$sql,LOG_DEBUG); + $this->_results = $this->query($sql); + return $this->_results; + } + + /** + * Create a new field into table + * + * @param string $table Name of table + * @param string $field_name Name of field to add + * @param string $field_desc Tableau associatif de description du champ a inserer[nom du parametre][valeur du parametre] + * @param string $field_position Optionnel ex.: "after champtruc" + * @return int <0 if KO, >0 if OK + */ + function DDLAddField($table,$field_name,$field_desc,$field_position="") + { + // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra + // ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment'); + $sql= "ALTER TABLE ".$table." ADD ".$field_name." "; + $sql.= $field_desc['type']; + if(preg_match("/^[^\s]/i",$field_desc['value'])) + if (! in_array($field_desc['type'],array('date','datetime'))) + { + $sql.= "(".$field_desc['value'].")"; + } + if(preg_match("/^[^\s]/i",$field_desc['attribute'])) + $sql.= " ".$field_desc['attribute']; + if(preg_match("/^[^\s]/i",$field_desc['null'])) + $sql.= " ".$field_desc['null']; + if(preg_match("/^[^\s]/i",$field_desc['default'])) + { + if(preg_match("/null/i",$field_desc['default'])) + $sql.= " default ".$field_desc['default']; + else + $sql.= " default '".$field_desc['default']."'"; + } + if(preg_match("/^[^\s]/i",$field_desc['extra'])) + $sql.= " ".$field_desc['extra']; + $sql.= " ".$field_position; + + dol_syslog(get_class($this)."::DDLAddField ".$sql,LOG_DEBUG); + if(! $this->query($sql)) + { + return -1; + } + else + { + return 1; + } + } + + /** + * Update format of a field into a table + * + * @param string $table Name of table + * @param string $field_name Name of field to modify + * @param string $field_desc Array with description of field format + * @return int <0 if KO, >0 if OK + */ + function DDLUpdateField($table,$field_name,$field_desc) + { + $sql = "ALTER TABLE ".$table; + $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type']; + if ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') { + $sql.="(".$field_desc['value'].")"; + } + + dol_syslog(get_class($this)."::DDLUpdateField ".$sql,LOG_DEBUG); + if (! $this->query($sql)) + return -1; + else + return 1; + } + + /** + * Drop a field from table + * + * @param string $table Name of table + * @param string $field_name Name of field to drop + * @return int <0 if KO, >0 if OK + */ + function DDLDropField($table,$field_name) + { + $sql= "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`"; + dol_syslog(get_class($this)."::DDLDropField ".$sql,LOG_DEBUG); + if (! $this->query($sql)) + { + $this->error=$this->lasterror(); + return -1; + } + else return 1; + } + + + /** + * Create a user and privileges to connect to database (even if database does not exists yet) + * + * @param string $dolibarr_main_db_host Ip serveur + * @param string $dolibarr_main_db_user Nom user a creer + * @param string $dolibarr_main_db_pass Mot de passe user a creer + * @param string $dolibarr_main_db_name Database name where user must be granted + * @return int <0 if KO, >=0 if OK + */ + function DDLCreateUser($dolibarr_main_db_host,$dolibarr_main_db_user,$dolibarr_main_db_pass,$dolibarr_main_db_name) + { + $sql = "INSERT INTO user "; + $sql.= "(Host,User,password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)"; + $sql.= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_user)."',password('".addslashes($dolibarr_main_db_pass)."')"; + $sql.= ",'Y','Y','Y','Y','Y','Y','Y','Y','Y')"; + + dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log + $resql=$this->query($sql); + if (! $resql) + { + return -1; + } + + $sql = "INSERT INTO db "; + $sql.= "(Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)"; + $sql.= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_name)."','".addslashes($dolibarr_main_db_user)."'"; + $sql.= ",'Y','Y','Y','Y','Y','Y','Y','Y','Y')"; + + dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); + $resql=$this->query($sql); + if (! $resql) + { + return -1; + } + + $sql="FLUSH Privileges"; + + dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); + $resql=$this->query($sql); + if (! $resql) + { + return -1; + } + + return 1; + } + + /** + * Return charset used to store data in database + * + * @return string Charset + */ + function getDefaultCharacterSetDatabase() + { + return 'UTF-8'; + } + + /** + * Return list of available charset that can be used to store data in database + * + * @return array List of Charset + */ + function getListOfCharacterSet() + { + $liste = array(); + $i=0; + $liste[$i]['charset'] = 'UTF-8'; + $liste[$i]['description'] = 'UTF-8'; + return $liste; + } + + /** + * Return collation used in database + * + * @return string Collation value + */ + function getDefaultCollationDatabase() + { + return 'UTF-8'; + } + + /** + * Return list of available collation that can be used for database + * + * @return array List of Collation + */ + function getListOfCollation() + { + $liste = array(); + $i=0; + $liste[$i]['charset'] = 'UTF-8'; + $liste[$i]['description'] = 'UTF-8'; + return $liste; + } + + /** + * Return full path of dump program + * + * @return string Full path of dump program + */ + function getPathOfDump() + { + $fullpathofdump='/pathtomysqldump/mysqldump'; + + $resql=$this->query('SHOW VARIABLES LIKE \'basedir\''); + if ($resql) + { + $liste=$this->fetch_array($resql); + $basedir=$liste['Value']; + $fullpathofdump=$basedir.(preg_match('/\/$/',$basedir)?'':'/').'bin/mysqldump'; + } + return $fullpathofdump; + } + + /** + * Return full path of restore program + * + * @return string Full path of restore program + */ + function getPathOfRestore() + { + $fullpathofimport='/pathtomysql/mysql'; + + $resql=$this->query('SHOW VARIABLES LIKE \'basedir\''); + if ($resql) + { + $liste=$this->fetch_array($resql); + $basedir=$liste['Value']; + $fullpathofimport=$basedir.(preg_match('/\/$/',$basedir)?'':'/').'bin/mysql'; + } + return $fullpathofimport; + } + + /** + * Return value of server parameters + * + * @param string $filter Filter list on a particular value + * @return array Array of key-values (key=>value) + */ + function getServerParametersValues($filter='') + { + $result=array(); + static $pragmas; + if (! isset($pragmas)) { + // Définition de la liste des pragmas utilisés qui ne retournent qu'une seule valeur + // indépendante de la base de données. + // cf. http://www.sqlite.org/pragma.html + $pragmas = array( + 'application_id', 'auto_vacuum', 'automatic_index', 'busy_timeout', 'cache_size', + 'cache_spill', 'case_sensitive_like', 'checkpoint_fullsync', 'collation_list', + 'compile_options', 'data_version', /*'database_list',*/ + 'defer_foreign_keys', 'encoding', 'foreign_key_check', 'freelist_count', + 'full_column_names', 'fullsync', 'ingore_check_constraints', 'integrity_check', + 'journal_mode', 'journal_size_limit', 'legacy_file_format', 'locking_mode', + 'max_page_count', 'page_count', 'page_size', 'parser_trace', + 'query_only', 'quick_check', 'read_uncommitted', 'recursive_triggers', + 'reverse_unordered_selects', 'schema_version', 'user_version', + 'secure_delete', 'short_column_names', 'shrink_memory', 'soft_heap_limit', + 'synchronous', 'temp_store', /*'temp_store_directory',*/ 'threads', + 'vdbe_addoptrace', 'vdbe_debug', 'vdbe_listing', 'vdbe_trace', + 'wal_autocheckpoint', + ); + } + + // TODO prendre en compte le filtre + foreach($pragmas as $var) { + $sql = "PRAGMA $var"; + $resql=$this->query($sql); + if ($resql) + { + $obj = $this->fetch_row($resql); + //dol_syslog(get_class($this)."::select_db getServerParametersValues $var=". print_r($obj, true), LOG_DEBUG); + $result[$var] = $obj[0]; + } + else { + // TODO Récupérer le message + $result[$var] = 'FAIL'; + } + } + return $result; + } + + /** + * Return value of server status + * + * @param string $filter Filter list on a particular value + * @return array Array of key-values (key=>value) + */ + function getServerStatusValues($filter='') + { + $result=array(); + /* + $sql='SHOW STATUS'; + if ($filter) $sql.=" LIKE '".$this->escape($filter)."'"; + $resql=$this->query($sql); + if ($resql) + { + while ($obj=$this->fetch_object($resql)) $result[$obj->Variable_name]=$obj->Value; + } + */ + + return $result; + } + + /** + * Permet le chargement d'une fonction personnalisee dans le moteur de base de donnees. + * Note: le nom de la fonction personnalisee est prefixee par 'db'. La fonction doit être + * statique et publique. Le nombre de parametres est determine automatiquement. + * + * @param string $name Le nom de la fonction a definir dans Sqlite + * @param int $arg_count Arg count + * @return void + */ + private function addCustomFunction($name, $arg_count = -1) { + if ($this->db) { + $localname = __CLASS__ . '::' . 'db' . $name; + $reflectClass = new ReflectionClass(__CLASS__); + $reflectFunction = $reflectClass->getMethod('db' . $name); + if ($arg_count < 0) { + $arg_count = $reflectFunction->getNumberOfParameters(); + } + if (!$this->db->createFunction($name, $localname, $arg_count)) + { + $this->error = "unable to create custom function '$name'"; + } + } + } + + /** + * Cette fonction est l'equivalent de la fonction MONTH de MySql. + * + * @param string $date Date + * @return integer + */ + public static function dbMONTH($date) + { + return date('n', strtotime($date)); + } + + /** + * calcule du numéro de semaine + * + * @param string $date Date + * @param int $mode Mode + * @return string + */ + public static function dbWEEK($date, $mode = 0) + { + $arr = date_parse($date); + $calc_year = 0; + return self::calc_week($arr['year'], $arr['month'], $arr['day'], self::week_mode($mode), $calc_year); + } + + /** + * db_CURDATE + * + * @return string + */ + public static function dbCURDATE() { + return date('Y-m-d'); + } + + /** + * db_CURTIME + * + * @return string + */ + public static function dbCURTIME() { + return date('H:i:s'); + } + + /** + * dbWEEKDAY + * + * @param int $date Date + * @return string + */ + public static function dbWEEKDAY($date) { + $arr = date_parse($date); + return self::calc_weekday(self::calc_daynr($arr['year'], $arr['month'], $arr['day']), 0); + + } + + /** + * Cette fonction est l'equivelent de la fonction date_format de MySQL. + * @staticvar string $mysql_replacement Les symboles formatage a remplacer + * + * @param string $date la date dans un format ISO + * @param string $format la chaine de formatage + * @return string La date formatee. + */ + public static function dbdate_format($date, $format) + { + static $mysql_replacement; + if (! isset($mysql_replacement)) { + $mysql_replacement = array( + '%' => '%', + 'a' => 'D', + 'b' => 'M', + 'c' => 'n', + 'D' => 'jS', + 'd' => 'd', + 'e' => 'j', + 'f' => 'u', + 'H' => 'H', + 'h' => 'h', + 'I' => 'h', + 'i' => 'i', + 'k' => 'H', + 'l' => 'g', + 'M' => 'F', + 'm' => 'm', + 'p' => 'A', + 'r' => 'h:i:s A', + 'S' => 's', + 's' => 's', + 'T' => 'H:i:s', + 'W' => 'l', + 'w' => 'w', + 'Y' => 'Y', + 'y' => 'y', + ); + } + + $fmt = ''; + $lg = strlen($format); + $state = 0; + $timestamp = strtotime($date); + $yday = date('z', $timestamp); + $month = (integer) date("n", $timestamp); + $year = (integer) date("Y", $timestamp); + $day = (integer) date("d", $timestamp); + for($idx = 0; $idx < $lg; ++$idx) { + $char = $format[$idx]; + if ($state == 0) { + if ($char == '%') { + $state = 1; + } else { + $fmt .= $char; + } + } + elseif ($state == 1) { + if (array_key_exists($char, $mysql_replacement)) { + $fmt .= $mysql_replacement[$char]; + } else { + $calc_year = 0; + switch ($char) { + case 'j': // day of the year 001 + $char = sprintf("%03d", $yday+1); + break; + case 'U': // mode 0: semaine 0 = premiere semaine complète qui commence un dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 4, $calc_year)); + break; + case 'u': // mode 1: semaine 0 = première semaine de 4 jours. Début le dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 1, $calc_year)); + break; + case 'V': // mode 2: semaine 1 = premiere semaine complète qui commence un dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 6, $calc_year)); + break; + case 'v': // mode 3: semaine 1 = premiere semaine de 4 jours. Début le lundi + $char = sprintf("%02d", self::calc_week($year, $month, $day, 3, $calc_year)); + break; + case 'X': + self::calc_week($year, $month, $day, 6, $calc_year); + $char = sprintf("%04d", $calc_year); + break; + case 'x': + self::calc_week($year, $month, $day, 3, $calc_year); + $char = sprintf("%04d", $calc_year); + break; + } + $fmt .= $char; + } + $state = 0; + } + } + return date($fmt, strtotime($date)); + } + + + /** + * calc_daynr + * + * @param string $year Year + * @param string $month Month + * @param string $day Day + * @return string La date formatee. + */ + private static function calc_daynr($year, $month, $day) { + $y = $year; + if ($y == 0 && $month == 0) return 0; + $num = (365* $y + 31 * ($month - 1) + $day); + if ($month <= 2) { + $y--; } + else { + $num -= floor(($month * 4 + 23) / 10); + } + $temp = floor(($y / 100 + 1) * 3 / 4); + return $num + floor($y / 4) - $temp; + } + + /** + * calc_weekday + * + * @param string $daynr ??? + * @param string $sunday_first_day_of_week ??? + */ + private static function calc_weekday($daynr, $sunday_first_day_of_week) { + $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7); + return $ret; + } + + /** + * calc_days_in_year + * + * @param string $year Year + * @return int Nb of days in year + */ + private static function calc_days_in_year($year) + { + return (($year & 3) == 0 && ($year%100 || ($year%400 == 0 && $year)) ? 366 : 365); + } + + /** + * week_mode + * + * @param string $mode Mode + * @return string Week format + */ + private static function week_mode($mode) { + $week_format= ($mode & 7); + if (!($week_format & self::WEEK_MONDAY_FIRST)) { + $week_format^= self::WEEK_FIRST_WEEKDAY; + } + return $week_format; + } + + /** + * calc_week + * + * @param string $year Year + * @param string $month Month + * @param string $day Day + * @param string $week_behaviour Week behaviour + * @param string $calc_year ??? + * @return string ??? + */ + private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year) { + $daynr=self::calc_daynr($year,$month,$day); + $first_daynr=self::calc_daynr($year,1,1); + $monday_first= ($week_behaviour & self::WEEK_MONDAY_FIRST) ? 1 : 0; + $week_year= ($week_behaviour & self::WEEK_YEAR) ? 1 : 0; + $first_weekday= ($week_behaviour & self::WEEK_FIRST_WEEKDAY) ? 1 : 0; + + $weekday=self::calc_weekday($first_daynr, !$monday_first); + $calc_year=$year; + + if ($month == 1 && $day <= 7-$weekday) + { + if (!$week_year && (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4))) + return 0; + $week_year= 1; + $calc_year--; + $first_daynr-= ($days=self::calc_days_in_year($calc_year)); + $weekday= ($weekday + 53*7- $days) % 7; + } + + if (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)) { + $days= $daynr - ($first_daynr+ (7-$weekday)); + } + else { + $days= $daynr - ($first_daynr - $weekday); + } + + if ($week_year && $days >= 52*7) + { + $weekday= ($weekday + self::calc_days_in_year($calc_year)) % 7; + if ((!$first_weekday && $weekday < 4) || ($first_weekday && $weekday == 0)) + { + $calc_year++; + return 1; + } + } + return floor($days/7+1); + } + +} + diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 17b8b8e8def4ab54480c41b1754ddc9a627a540e..017d1eb86624320b3a0f10f94a352b8b6430008c 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -39,166 +39,166 @@ abstract class DolibarrModules */ public $db; - /** - * @var string Relative path to module style sheet - * @deprecated - */ - public $style_sheet = ''; - - /** - * @var array Paths to create when module is activated - */ - public $dirs = array(); - - /** - * @var array Module boxes - */ - public $boxes = array(); - - /** - * @var array Module constants - */ - public $const = array(); - - /** - * @var array Module access rights - */ - public $rights; - - /** - * @var string Module access rights family - */ - public $rights_class; - - /** - * @var array Module menu entries - */ - public $menu = array(); - - /** - * @var array Module parts - * array( - * // Set this to 1 if module has its own trigger directory (/mymodule/core/triggers) - * 'triggers' => 0, - * // Set this to 1 if module has its own login method directory (/mymodule/core/login) + /** + * @var string Relative path to module style sheet + * @deprecated + */ + public $style_sheet = ''; + + /** + * @var array Paths to create when module is activated + */ + public $dirs = array(); + + /** + * @var array Module boxes + */ + public $boxes = array(); + + /** + * @var array Module constants + */ + public $const = array(); + + /** + * @var array Module access rights + */ + public $rights; + + /** + * @var string Module access rights family + */ + public $rights_class; + + /** + * @var array Module menu entries + */ + public $menu = array(); + + /** + * @var array Module parts + * array( + * // Set this to 1 if module has its own trigger directory (/mymodule/core/triggers) + * 'triggers' => 0, + * // Set this to 1 if module has its own login method directory (/mymodule/core/login) * 'login' => 0, - * // Set this to 1 if module has its own substitution function file (/mymodule/core/substitutions) + * // Set this to 1 if module has its own substitution function file (/mymodule/core/substitutions) * 'substitutions' => 0, - * // Set this to 1 if module has its own menus handler directory (/mymodule/core/menus) + * // Set this to 1 if module has its own menus handler directory (/mymodule/core/menus) * 'menus' => 0, - * // Set this to 1 if module has its own theme directory (/mymodule/theme) + * // Set this to 1 if module has its own theme directory (/mymodule/theme) * 'theme' => 0, - * // Set this to 1 if module overwrite template dir (/mymodule/core/tpl) - * 'tpl' => 0, - * // Set this to 1 if module has its own barcode directory (/mymodule/core/modules/barcode) + * // Set this to 1 if module overwrite template dir (/mymodule/core/tpl) + * 'tpl' => 0, + * // Set this to 1 if module has its own barcode directory (/mymodule/core/modules/barcode) * 'barcode' => 0, - * // Set this to 1 if module has its own models directory (/mymodule/core/modules/xxx) + * // Set this to 1 if module has its own models directory (/mymodule/core/modules/xxx) * 'models' => 0, - * // Set this to relative path of css file if module has its own css file + * // Set this to relative path of css file if module has its own css file * 'css' => '/mymodule/css/mymodule.css.php', - * // Set this to relative path of js file if module must load a js on all pages + * // Set this to relative path of js file if module must load a js on all pages * 'js' => '/mymodule/js/mymodule.js', - * // Set here all hooks context managed by module + * // Set here all hooks context managed by module * 'hooks' => array('hookcontext1','hookcontext2'), - * // Set here all workflow context managed by module + * // Set here all workflow context managed by module * 'workflow' => array( - * 'WORKFLOW_MODULE1_YOURACTIONTYPE_MODULE2' = >array( - * 'enabled' => '! empty($conf->module1->enabled) && ! empty($conf->module2->enabled)', - * 'picto'=>'yourpicto@mymodule' - * ) - * ) - * ) - */ - public $module_parts = array(); - - /** - * @var string Module documents ? - * @deprecated Seems unused anywhere - */ - public $docs; - - /** - * @var string ? - * @deprecated Seems unused anywhere - */ - public $dbversion = "-"; - - /** - * @var string Error message - */ - public $error; - - /** - * @var int Module unique ID - */ - public $numero; - - /** - * @var string Module name - */ - public $name; - - /** - * @var string Module version - */ - public $version; - - /** - * @var string Module description - */ - public $description; - - /** - * @var string[] Module language files - */ - public $langfiles; - - /** - * @var string Module export code - */ - public $export_code; - - /** - * @var string Module export label - */ - public $export_label; - - /** - * @var string Module import code - */ - public $import_code; - - /** - * @var string Module import label - */ - public $import_label; - - /** - * @var string Module constant name - */ - public $const_name; - - /** - * @var bool Module can't be disabled - */ - public $always_enabled; - - /** - * @var bool Module is enabled globally (Multicompany support) - */ - public $core_enabled; - - /** - * Enables a module. - * Inserts all informations into database - * + * 'WORKFLOW_MODULE1_YOURACTIONTYPE_MODULE2' = >array( + * 'enabled' => '! empty($conf->module1->enabled) && ! empty($conf->module2->enabled)', + * 'picto'=>'yourpicto@mymodule' + * ) + * ) + * ) + */ + public $module_parts = array(); + + /** + * @var string Module documents ? + * @deprecated Seems unused anywhere + */ + public $docs; + + /** + * @var string ? + * @deprecated Seems unused anywhere + */ + public $dbversion = "-"; + + /** + * @var string Error message + */ + public $error; + + /** + * @var int Module unique ID + */ + public $numero; + + /** + * @var string Module name + */ + public $name; + + /** + * @var string Module version + */ + public $version; + + /** + * @var string Module description + */ + public $description; + + /** + * @var string[] Module language files + */ + public $langfiles; + + /** + * @var string Module export code + */ + public $export_code; + + /** + * @var string Module export label + */ + public $export_label; + + /** + * @var string Module import code + */ + public $import_code; + + /** + * @var string Module import label + */ + public $import_label; + + /** + * @var string Module constant name + */ + public $const_name; + + /** + * @var bool Module can't be disabled + */ + public $always_enabled; + + /** + * @var bool Module is enabled globally (Multicompany support) + */ + public $core_enabled; + + /** + * Enables a module. + * Inserts all informations into database + * * @param array $array_sql SQL requests to be executed when enabling module - * @param string $options String with options when disabling module: - * 'noboxes' = Do not insert boxes - * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation - * - * @return int 1 if OK, 0 if KO - */ + * @param string $options String with options when disabling module: + * 'noboxes' = Do not insert boxes + * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation + * + * @return int 1 if OK, 0 if KO + */ function _init($array_sql, $options='') { global $conf; @@ -232,12 +232,12 @@ abstract class DolibarrModules // Execute addons requests $num=count($array_sql); - for ($i = 0; $i < $num; $i++) + for ($i = 0; $i < $num; $i++) { if (! $err) { $val=$array_sql[$i]; - $sql=$val; + $sql=$val; $ignoreerror=0; if (is_array($val)) { @@ -367,12 +367,12 @@ abstract class DolibarrModules // If module name translation using it's unique id does not exists, we take use its name to find translation if (is_array($this->langfiles)) { - foreach($this->langfiles as $val) - { - if ($val) $langs->load($val); - } + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } } - return $langs->trans($this->name); + return $langs->trans($this->name); } } @@ -389,20 +389,20 @@ abstract class DolibarrModules if ($langs->trans("Module".$this->numero."Desc") != ("Module".$this->numero."Desc")) { - // If module description translation exists + // If module description translation exists return $langs->trans("Module".$this->numero."Desc"); } else - { + { // If module description translation using it's unique id does not exists, we take use its name to find translation if (is_array($this->langfiles)) { - foreach($this->langfiles as $val) - { - if ($val) $langs->load($val); - } + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } } - return $langs->trans($this->description); + return $langs->trans($this->description); } } @@ -429,7 +429,7 @@ abstract class DolibarrModules else $ret=$langs->trans("VersionUnknown"); if (preg_match('/_deprecated/',$this->version)) $ret.=' ('.$langs->trans("Deprecated").')'; - return $ret; + return $ret; } @@ -582,9 +582,9 @@ abstract class DolibarrModules global $conf; $error=0; - $dirfound=0; + $dirfound=0; - if (empty($reldir)) return 1; + if (empty($reldir)) return 1; include_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; @@ -599,10 +599,10 @@ abstract class DolibarrModules $handle=@opendir($dir); // Dir may not exists if (is_resource($handle)) { - $dirfound++; + $dirfound++; - // Run llx_mytable.sql files - while (($file = readdir($handle))!==false) + // Run llx_mytable.sql files + while (($file = readdir($handle))!==false) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') { @@ -613,8 +613,8 @@ abstract class DolibarrModules rewinddir($handle); - // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) - while (($file = readdir($handle))!==false) + // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) + while (($file = readdir($handle))!==false) { if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') { @@ -626,7 +626,7 @@ abstract class DolibarrModules rewinddir($handle); // Run data_xxx.sql files (Must be done after llx_mytable.key.sql) - while (($file = readdir($handle))!==false) + while (($file = readdir($handle))!==false) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data') { @@ -638,7 +638,7 @@ abstract class DolibarrModules rewinddir($handle); // Run update_xxx.sql files - while (($file = readdir($handle))!==false) + while (($file = readdir($handle))!==false) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update') { @@ -671,9 +671,9 @@ abstract class DolibarrModules */ function insert_boxes($option='') { - require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php'; + require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php'; - global $conf; + global $conf; $err=0; @@ -681,8 +681,8 @@ abstract class DolibarrModules { $pos_name = InfoBox::getListOfPagesForBoxes(); - foreach ($this->boxes as $key => $value) - { + foreach ($this->boxes as $key => $value) + { $file = isset($this->boxes[$key]['file'])?$this->boxes[$key]['file']:''; $note = isset($this->boxes[$key]['note'])?$this->boxes[$key]['note']:''; $enabledbydefaulton = isset($this->boxes[$key]['enabledbydefaulton'])?$this->boxes[$key]['enabledbydefaulton']:'Home'; @@ -724,15 +724,15 @@ abstract class DolibarrModules foreach ($pos_name as $key2 => $val2) { - //print 'key2='.$key2.'-val2='.$val2."<br>\n"; + //print 'key2='.$key2.'-val2='.$val2."<br>\n"; if ($enabledbydefaulton && $val2 != $enabledbydefaulton) continue; // Not enabled by default onto this page. - $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes (box_id,position,box_order,fk_user,entity)"; - $sql.= " VALUES (".$lastid.", ".$key2.", '0', 0, ".$conf->entity.")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes (box_id,position,box_order,fk_user,entity)"; + $sql.= " VALUES (".$lastid.", ".$key2.", '0', 0, ".$conf->entity.")"; - dol_syslog(get_class($this)."::insert_boxes onto page ".$key2."=".$val2."", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; + dol_syslog(get_class($this)."::insert_boxes onto page ".$key2."=".$val2."", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; } } @@ -741,7 +741,7 @@ abstract class DolibarrModules $this->db->commit(); } else - { + { $this->error=$this->db->lasterror(); $this->db->rollback(); } @@ -781,11 +781,22 @@ abstract class DolibarrModules if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility - $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes"; - $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def"; - $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid"; - $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'"; - $sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; + if ($this->db->type == 'sqlite3') { + // sqlite doesn't support "USING" syntax. + // TODO: remove this dependency. + $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes "; + $sql .= "WHERE ".MAIN_DB_PREFIX."boxes.box_id IN ("; + $sql .= "SELECT ".MAIN_DB_PREFIX."boxes_def.rowid "; + $sql .= "FROM ".MAIN_DB_PREFIX."boxes_def "; + $sql .= "WHERE ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."') "; + $sql .= "AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; + } else { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes"; + $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def"; + $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid"; + $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'"; + $sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; + } dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG); $resql=$this->db->query($sql); @@ -1012,7 +1023,7 @@ abstract class DolibarrModules if ($resql) { $obj=$this->db->fetch_object($resql); - if (! empty($obj->value) && ! empty($this->rights)) + if ($obj !== null && ! empty($obj->value) && ! empty($this->rights)) { // Si module actif foreach ($this->rights as $key => $value) @@ -1027,54 +1038,54 @@ abstract class DolibarrModules if (empty($r_type)) $r_type='w'; - // Search if perm already present - $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."rights_def"; - $sql.= " WHERE id = ".$r_id." AND entity = ".$entity; - $resqlselect=$this->db->query($sql); + // Search if perm already present + $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."rights_def"; + $sql.= " WHERE id = ".$r_id." AND entity = ".$entity; + $resqlselect=$this->db->query($sql); - $obj = $this->db->fetch_object($resqlselect); + $obj = $this->db->fetch_object($resqlselect); if ($obj->nb == 0) { - if (dol_strlen($r_perms) ) - { - if (dol_strlen($r_subperms) ) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; - $sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)"; - $sql.= " VALUES "; - $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')"; - } - else - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; - $sql.= " (id, entity, libelle, module, type, bydefault, perms)"; - $sql.= " VALUES "; - $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."')"; - } - } - else - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def "; - $sql .= " (id, entity, libelle, module, type, bydefault)"; - $sql .= " VALUES "; - $sql .= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.")"; - } - - $resqlinsert=$this->db->query($sql,1); - - if (! $resqlinsert) - { - if ($this->db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS") - { - $this->error=$this->db->lasterror(); - $err++; - break; - } - else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO); - - } - - $this->db->free($resqlinsert); + if (dol_strlen($r_perms) ) + { + if (dol_strlen($r_subperms) ) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; + $sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)"; + $sql.= " VALUES "; + $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')"; + } + else + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; + $sql.= " (id, entity, libelle, module, type, bydefault, perms)"; + $sql.= " VALUES "; + $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."')"; + } + } + else + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def "; + $sql .= " (id, entity, libelle, module, type, bydefault)"; + $sql .= " VALUES "; + $sql .= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.")"; + } + + $resqlinsert=$this->db->query($sql,1); + + if (! $resqlinsert) + { + if ($this->db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS") + { + $this->error=$this->db->lasterror(); + $err++; + break; + } + else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO); + + } + + $this->db->free($resqlinsert); } $this->db->free($resqlselect); @@ -1082,9 +1093,9 @@ abstract class DolibarrModules // If we want to init permissions on admin users if ($reinitadminperms) { - if (! class_exists('User')) { - require DOL_DOCUMENT_ROOT . '/user/class/user.class.php'; - } + if (! class_exists('User')) { + require DOL_DOCUMENT_ROOT . '/user/class/user.class.php'; + } $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."user WHERE admin = 1"; dol_syslog(get_class($this)."::insert_permissions Search all admin users", LOG_DEBUG); $resqlseladmin=$this->db->query($sql,1); @@ -1099,7 +1110,7 @@ abstract class DolibarrModules $tmpuser=new User($this->db); $tmpuser->fetch($obj2->rowid); if (!empty($tmpuser->id)) { - $tmpuser->addrights($r_id); + $tmpuser->addrights($r_id); } $i++; } @@ -1158,7 +1169,7 @@ abstract class DolibarrModules */ function insert_menus() { - global $user; + global $user; require_once DOL_DOCUMENT_ROOT . '/core/class/menubase.class.php'; @@ -1415,68 +1426,68 @@ abstract class DolibarrModules */ function insert_module_parts() { - global $conf; + global $conf; - $error=0; - $entity=$conf->entity; + $error=0; + $entity=$conf->entity; - if (is_array($this->module_parts) && ! empty($this->module_parts)) - { - foreach($this->module_parts as $key => $value) - { + if (is_array($this->module_parts) && ! empty($this->module_parts)) + { + foreach($this->module_parts as $key => $value) + { if (is_array($value) && count($value) == 0) continue; // Discard empty arrays - $newvalue = $value; - - // Serialize array parameters - if (is_array($value)) - { - // Can defined other parameters - if (is_array($value['data']) && ! empty($value['data'])) - { - $newvalue = json_encode($value['data']); - if (isset($value['entity'])) $entity = $value['entity']; - } - else - { - $newvalue = json_encode($value); - } - } - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; - $sql.= "name"; - $sql.= ", type"; - $sql.= ", value"; - $sql.= ", note"; - $sql.= ", visible"; - $sql.= ", entity"; - $sql.= ")"; - $sql.= " VALUES ("; - $sql.= $this->db->encrypt($this->const_name."_".strtoupper($key), 1); - $sql.= ", 'chaine'"; - $sql.= ", ".$this->db->encrypt($newvalue, 1); - $sql.= ", null"; - $sql.= ", '0'"; - $sql.= ", ".$entity; - $sql.= ")"; - - dol_syslog(get_class($this)."::insert_const_".$key."", LOG_DEBUG); - $resql=$this->db->query($sql,1); - if (! $resql) - { - if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $error++; - $this->error=$this->db->lasterror(); - } - else - { - dol_syslog(get_class($this)."::insert_const_".$key." Record already exists.", LOG_WARNING); - } - } - } - } - return $error; + $newvalue = $value; + + // Serialize array parameters + if (is_array($value)) + { + // Can defined other parameters + if (is_array($value['data']) && ! empty($value['data'])) + { + $newvalue = json_encode($value['data']); + if (isset($value['entity'])) $entity = $value['entity']; + } + else + { + $newvalue = json_encode($value); + } + } + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; + $sql.= "name"; + $sql.= ", type"; + $sql.= ", value"; + $sql.= ", note"; + $sql.= ", visible"; + $sql.= ", entity"; + $sql.= ")"; + $sql.= " VALUES ("; + $sql.= $this->db->encrypt($this->const_name."_".strtoupper($key), 1); + $sql.= ", 'chaine'"; + $sql.= ", ".$this->db->encrypt($newvalue, 1); + $sql.= ", null"; + $sql.= ", '0'"; + $sql.= ", ".$entity; + $sql.= ")"; + + dol_syslog(get_class($this)."::insert_const_".$key."", LOG_DEBUG); + $resql=$this->db->query($sql,1); + if (! $resql) + { + if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $error++; + $this->error=$this->db->lasterror(); + } + else + { + dol_syslog(get_class($this)."::insert_const_".$key." Record already exists.", LOG_WARNING); + } + } + } + } + return $error; } /** @@ -1486,31 +1497,31 @@ abstract class DolibarrModules */ function delete_module_parts() { - global $conf; - - $err=0; - $entity=$conf->entity; - - if (is_array($this->module_parts) && ! empty($this->module_parts)) - { - foreach($this->module_parts as $key => $value) - { - // If entity is defined - if (is_array($value) && isset($value['entity'])) $entity = $value['entity']; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->const_name."_".strtoupper($key)."'"; - $sql.= " AND entity = ".$entity; - - dol_syslog(get_class($this)."::delete_const_".$key."", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $this->error=$this->db->lasterror(); - $err++; - } - } - } - return $err; + global $conf; + + $err=0; + $entity=$conf->entity; + + if (is_array($this->module_parts) && ! empty($this->module_parts)) + { + foreach($this->module_parts as $key => $value) + { + // If entity is defined + if (is_array($value) && isset($value['entity'])) $entity = $value['entity']; + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->const_name."_".strtoupper($key)."'"; + $sql.= " AND entity = ".$entity; + + dol_syslog(get_class($this)."::delete_const_".$key."", LOG_DEBUG); + if (! $this->db->query($sql)) + { + $this->error=$this->db->lasterror(); + $err++; + } + } + } + return $err; } } diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php index bdb19778c87e05b035ec5c0f76c008bd398a883d..d2cdb71e429e6211a65b10418546509a5873a8ca 100755 --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php @@ -508,7 +508,7 @@ class pdf_standard extends ModeleExpenseReport */ // Filligrane brouillon - if ($object->fk_c_expensereport_statuts==1 && ! empty($conf->global->EXPENSEREPORT_FREE_TEXT)) + if ($object->fk_statut==1 && ! empty($conf->global->EXPENSEREPORT_FREE_TEXT)) { pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->EXPENSEREPORT_FREE_TEXT); } @@ -640,7 +640,7 @@ class pdf_standard extends ModeleExpenseReport $pdf->MultiCell(96,4,$outputlangs->transnoentities("DateCreation")." : ".dol_print_date($object->date_create,"day",false,$outpulangs),0,'L'); } - if ($object->fk_c_expensereport_statuts==99) + if ($object->fk_statut==99) { if ($object->fk_user_refuse > 0) { @@ -656,7 +656,7 @@ class pdf_standard extends ModeleExpenseReport $pdf->MultiCell(96,4,$outputlangs->transnoentities("DATE_REFUS")." : ".dol_print_date($object->date_refuse,"day",false,$outpulangs),0,'L'); } } - else if($object->fk_c_expensereport_statuts==4) + else if($object->fk_statut==4) { if ($object->fk_user_cancel > 0) { @@ -686,7 +686,7 @@ class pdf_standard extends ModeleExpenseReport } } - if($object->fk_c_expensereport_statuts==6) + if($object->fk_statut==6) { if ($object->fk_user_paid > 0) { diff --git a/htdocs/core/modules/modExpenseReport.class.php b/htdocs/core/modules/modExpenseReport.class.php index 5d826ae9a54e31344a5882d977932e32406679ba..53289c512ff83ea74ea7a9ac0276e68b05314e96 100755 --- a/htdocs/core/modules/modExpenseReport.class.php +++ b/htdocs/core/modules/modExpenseReport.class.php @@ -84,7 +84,7 @@ class modExpenseReport extends DolibarrModules // Dependencies $this->depends = array(); // List of modules id that must be enabled if this module is enabled - $this->conflictwith = array("modDeplacement"); + // $this->conflictwith = array("modDeplacement"); // Deactivate for access on old information $this->requiredby = array(); // List of modules id to disable if this one is disabled $this->phpmin = array(4,3); // Minimum version of PHP required by module $this->need_dolibarr_version = array(3,7); // Minimum version of Dolibarr required by module @@ -270,7 +270,7 @@ class modExpenseReport extends DolibarrModules 'titre'=>'ListToApprove', 'mainmenu'=>'hrm', 'leftmenu'=>'expensereport_detaillist_approve', - 'url'=>'/expensereport/list.php?search_state=2', + 'url'=>'/expensereport/list.php?search_status=2', 'langs'=>'trips', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>100, 'enabled'=>'$conf->expensereport->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 7f0115b83bcda394cfa06e01b0cf885f29e91d4e..b6b26cc380dc7febbb3b8e3517a1d08f7c2616ba 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -65,7 +65,7 @@ if (empty($reshook) && ! empty($extrafields->attribute_label)) print '<td align="right"><a href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=edit_extras&attribute=' . $key . '">' . img_edit().'</a></td>'; print '</tr></table>'; - print '<td colspan="5">'; + print '<td colspan="'.$cols.'">'; // Convert date into timestamp format if (in_array($extrafields->attribute_type[$key], array('date','datetime'))) { diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 79652c9c5c4cac89cf703824bfd7ec7258db1ce8..1fd86ed871dd0949c9ad06f5ebf00b914a1cd148 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -52,7 +52,7 @@ if (empty($usemargins)) $usemargins=0; <?php if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { ?> <td align="center"><?php $coldisplay++; ?><?php echo ($i+1); ?></td> <?php } ?> - <td><?php $coldisplay++; ?><div id="row-<?php echo $line->id; ?>"></div> + <td><?php $coldisplay++; ?><div id="line_<?php echo $line->id; ?>"></div> <?php if (($line->info_bits & 2) == 2) { ?> <a href="<?php echo DOL_URL_ROOT.'/comm/remx.php?id='.$this->socid; ?>"> <?php @@ -183,7 +183,7 @@ if (empty($usemargins)) $usemargins=0; <td align="center"><?php $coldisplay++; ?> <?php if (($line->info_bits & 2) == 2) { ?> <?php } else { ?> - <a href="<?php echo $_SERVER["PHP_SELF"].'?id='.$this->id.'&action=editline&lineid='.$line->id.'#'.$line->id; ?>"> + <a href="<?php echo $_SERVER["PHP_SELF"].'?id='.$this->id.'&action=editline&lineid='.$line->id.'#line_'.$line->id; ?>"> <?php echo img_edit(); ?> </a> <?php } ?> diff --git a/htdocs/expensereport/ajax/index.html b/htdocs/expensereport/ajax/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 86c113c24da70fa41ea3836168455b67e281e16d..c71705628b675363c61ed670721140e3b48dc3d2 100755 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -109,7 +109,7 @@ if ($action == 'add' && $user->rights->expensereport->creer) $object->date_debut = $date_start; $object->date_fin = $date_end; - $object->fk_c_expensereport_statuts = 1; + $object->fk_statut = 1; $object->fk_c_paiement = GETPOST('fk_c_paiement','int'); $object->fk_user_validator = GETPOST('fk_user_validator','int'); $object->note_public = GETPOST('note_public'); @@ -151,7 +151,7 @@ if ($action == 'update' && $user->rights->expensereport->creer) $object->date_debut = $date_start; $object->date_fin = $date_end; - if($object->fk_c_expensereport_statuts < 3) + if($object->fk_statut < 3) { $object->fk_user_validator = GETPOST('fk_user_validator','int'); } @@ -733,12 +733,12 @@ if ($action == "confirm_paid" && GETPOST('confirm')=="yes" && $id > 0 && $user-> $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, $cat1, $user); if ($insertid > 0): - $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport as d"; $sql.= " SET integration_compta = 1, fk_bank_account = $idAccount"; $sql.= " WHERE rowid = $idTrip"; $resql=$db->query($sql); if($result): - Header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + Header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); exit; else: dol_print_error($db); @@ -1197,7 +1197,7 @@ else $head = expensereport_prepare_head($object); - if ($action == 'edit' && ($object->fk_c_expensereport_statuts < 3 || $object->fk_c_expensereport_statuts==99)) + if ($action == 'edit' && ($object->fk_statut < 3 || $object->fk_statut==99)) { print "<form name='update' action=\"".$_SERVER['PHP_SELF']."\" method=\"post\">\n"; print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; @@ -1205,7 +1205,7 @@ else dol_fiche_head($head, 'card', $langs->trans("TripCard"), 0, 'trip'); - if($object->fk_c_expensereport_statuts==99) + if($object->fk_statut==99) { print '<input type="hidden" name="action" value="updateFromRefuse">'; } @@ -1246,7 +1246,7 @@ else print '</tr>'; } - if($object->fk_c_expensereport_statuts<3) + if($object->fk_statut<3) { print '<tr>'; print '<td>'.$langs->trans("VALIDATOR").'</td>'; // Approbator @@ -1275,7 +1275,7 @@ else $userfee->fetch($object->fk_user_author); print $userfee->getNomUrl(1); print '</td></tr>'; - if ($object->fk_c_expensereport_statuts==6) + if ($object->fk_statut==6) { print '<tr>'; print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>'; @@ -1437,7 +1437,7 @@ else print '<td>'.$langs->trans("DATE_SAVE").'</td>'; print '<td>'.dol_print_date($object->date_create,'dayhour').'</td></tr>'; print '</tr>'; - if($object->fk_c_expensereport_statuts==6) + if($object->fk_statut==6) { print '<tr>'; print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>'; @@ -1452,7 +1452,7 @@ else print '</tr>'; } - if($object->fk_c_expensereport_statuts<3) // informed + if($object->fk_statut<3) // informed { print '<tr>'; print '<td>'.$langs->trans("VALIDATOR").'</td>'; @@ -1465,7 +1465,7 @@ else } print '</td></tr>'; } - elseif($object->fk_c_expensereport_statuts==4) + elseif($object->fk_statut==4) { print '<tr>'; print '<td>'.$langs->trans("CANCEL_USER").'</span></td>'; @@ -1504,7 +1504,7 @@ else print '</tr>'; } - if($object->fk_c_expensereport_statuts==99 || !empty($object->detail_refuse)) + if($object->fk_statut==99 || !empty($object->detail_refuse)) { print '<tr>'; print '<td>'.$langs->trans("REFUSEUR").'</td>'; @@ -1529,9 +1529,9 @@ else $sql.= ' fde.fk_c_tva as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det fde'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON fde.fk_c_type_fees=ctf.id'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet pjt ON fde.fk_projet=pjt.rowid'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid'; $sql.= ' WHERE fde.fk_expensereport = '.$id; $resql = $db->query($sql); @@ -1566,7 +1566,7 @@ else print '<td style="text-align:right;">'.$langs->trans('AmountTTC').'</td>'; } // Ajout des boutons de modification/suppression - if ($object->fk_c_expensereport_statuts < 2 || $object->fk_c_expensereport_statuts==99) + if ($object->fk_statut < 2 || $object->fk_statut==99) { print '<td style="text-align:right;"></td>'; } @@ -1609,7 +1609,7 @@ else } // Ajout des boutons de modification/suppression - if($object->fk_c_expensereport_statuts<2 OR $object->fk_c_expensereport_statuts==99) + if($object->fk_statut<2 OR $object->fk_statut==99) { print '<td style="text-align:right;" class="nowrap">'; print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&rowid='.$objp->rowid.'#'.$objp->rowid.'">'; @@ -1689,7 +1689,7 @@ else //print '</div>'; // Add a line - if (($object->fk_c_expensereport_statuts==0 || $object->fk_c_expensereport_statuts==99) && $action != 'editline') + if (($object->fk_statut==0 || $object->fk_statut==99) && $action != 'editline') { print_fiche_titre($langs->trans("AddLine"),'',''); @@ -1712,17 +1712,17 @@ else print '<tr>'; - // Sélection date + // Select date print '<td style="text-align:center;">'; $form->select_date($date?$date:-1,'date'); print '</td>'; - // Sélection projet + // Select project print '<td>'; $formproject->select_projects(-1, GETPOST('fk_projet'), 'fk_projet', 0, 0, 1, 1); print '</td>'; - // Sélection type + // Select type print '<td>'; select_type_fees_id(GETPOST('fk_c_type_fees'),'fk_c_type_fees',1); print '</td>'; @@ -1732,7 +1732,7 @@ else print '<textarea class="flat_ndf centpercent" name="comments">'.GETPOST('comments').'</textarea>'; print '</td>'; - // Sélection TVA + // Select VAT print '<td style="text-align:right;">'; $defaultvat=-1; if (! empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none'; @@ -1747,7 +1747,7 @@ else print '<input type="text" size="6" name="value_unit" value="'.GETPOST('value_unit').'">'; print '</td>'; - // Quantité + // Quantity print '<td style="text-align:right;">'; print '<input type="text" size="4" name="qty" value="'.GETPOST('qty').'">'; print '</td>'; @@ -1799,7 +1799,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_author == user courant * Afficher : "Enregistrer" / "Modifier" / "Supprimer" */ - if ($user->rights->expensereport->creer && $object->fk_c_expensereport_statuts==0) + if ($user->rights->expensereport->creer && $object->fk_statut==0) { if ($object->fk_user_author == $user->id) { @@ -1825,7 +1825,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_author == user courant * Afficher : "Enregistrer" / "Modifier" / "Supprimer" */ - if($user->rights->expensereport->creer && $object->fk_c_expensereport_statuts==99) + if($user->rights->expensereport->creer && $object->fk_statut==99) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) { @@ -1845,7 +1845,7 @@ if ($action != 'create' && $action != 'edit') } } - if ($user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts==5) + if ($user->rights->expensereport->to_paid && $object->fk_statut==5) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) { @@ -1859,7 +1859,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_validator == user courant * Afficher : "Valider" / "Refuser" / "Supprimer" */ - if ($object->fk_c_expensereport_statuts == 2) + if ($object->fk_statut == 2) { if ($object->fk_user_author == $user->id) { @@ -1868,7 +1868,7 @@ if ($action != 'create' && $action != 'edit') } } - if ($user->rights->expensereport->approve && $object->fk_c_expensereport_statuts == 2) + if ($user->rights->expensereport->approve && $object->fk_statut == 2) { //if($object->fk_user_validator==$user->id) //{ @@ -1895,7 +1895,7 @@ if ($action != 'create' && $action != 'edit') * ET user à droit de "to_paid" * Afficher : "Annuler" / "Payer" / "Supprimer" */ - if ($user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts == 5) + if ($user->rights->expensereport->to_paid && $object->fk_statut == 5) { // Payer print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=paid&id='.$id.'">'.$langs->trans('TO_PAID').'</a>'; @@ -1918,7 +1918,7 @@ if ($action != 'create' && $action != 'edit') * ET user à droit "to_paid" * Afficher : "Annuler" */ - if ($user->rights->expensereport->approve && $user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts==6) + if ($user->rights->expensereport->approve && $user->rights->expensereport->to_paid && $object->fk_statut==6) { // Annuler print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$id.'">'.$langs->trans('Cancel').'</a>'; @@ -1933,7 +1933,7 @@ if ($action != 'create' && $action != 'edit') * ET user à droit "supprimer" * Afficher : "Supprimer" */ - if ($user->rights->expensereport->supprimer && $object->fk_c_expensereport_statuts==4) + if ($user->rights->expensereport->supprimer && $object->fk_statut==4) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) @@ -1959,7 +1959,7 @@ print '<div style="width:50%">'; /* * Documents generes */ -if($user->rights->expensereport->export && $object->fk_c_expensereport_statuts>0 && $action != 'edit') +if($user->rights->expensereport->export && $object->fk_statut>0 && $action != 'edit') { $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref); diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index b31329fae951bee1204a63842079577b15a61680..864c169c11c55f843f9306a0e7a796c95e6fc455 100755 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1,5 +1,22 @@ <?php -require_once(DOL_DOCUMENT_ROOT ."/core/class/commonobject.class.php"); +/* Copyright (C) 2011 Dimitri Mouillard <dmouillard@teclib.com> + * Copyright (C) 2015 Laurent Destailleur <eldy@users.sourceforge.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; /** * Class to manage Trips and Expenses @@ -26,7 +43,7 @@ class ExpenseReport extends CommonObject var $fk_user_validator; var $status; - var $fk_c_expensereport_statuts; // -- 1=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied + var $fk_statut; // -- 1=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied var $fk_c_paiement; var $user_author_infos; @@ -133,7 +150,7 @@ class ExpenseReport extends CommonObject $sql.= ",date_create"; $sql.= ",fk_user_author"; $sql.= ",fk_user_validator"; - $sql.= ",fk_c_expensereport_statuts"; + $sql.= ",fk_statut"; $sql.= ",fk_c_paiement"; $sql.= ",note_public"; $sql.= ",note_private"; @@ -147,7 +164,7 @@ class ExpenseReport extends CommonObject $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", ".($user->id > 0 ? $user->id:"null"); $sql.= ", ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null"); - $sql.= ", ".($this->fk_c_expensereport_statuts > 1 ? $this->fk_c_expensereport_statuts:0); + $sql.= ", ".($this->fk_statut > 1 ? $this->fk_statut:0); $sql.= ", ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement:"null"); $sql.= ", ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); $sql.= ", ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); @@ -231,7 +248,7 @@ class ExpenseReport extends CommonObject $sql.= " , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null"); $sql.= " , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid:"null"); $sql.= " , fk_user_paid = ".($this->fk_user_paid > 0 ? $this->fk_user_paid:"null"); - $sql.= " , fk_c_expensereport_statuts = ".($this->fk_c_expensereport_statuts >= 0 ? $this->fk_c_expensereport_statuts:'0'); + $sql.= " , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut:'0'); $sql.= " , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement:"null"); $sql.= " , note_public = ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"''"); $sql.= " , note_private = ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"''"); @@ -267,10 +284,10 @@ class ExpenseReport extends CommonObject $sql.= " d.date_refuse, d.date_cancel,"; // ACTIONS $sql.= " d.total_ht, d.total_ttc, d.total_tva,"; // TOTAUX (int) $sql.= " d.date_debut, d.date_fin, d.date_create, d.date_valid, d.date_approve, d.date_paiement,"; // DATES (datetime) - $sql.= " d.fk_user_author, d.fk_user_validator, d.fk_c_expensereport_statuts as status, d.fk_c_paiement,"; + $sql.= " d.fk_user_author, d.fk_user_validator, d.fk_statut as status, d.fk_c_paiement,"; $sql.= " d.fk_user_valid, d.fk_user_approve, d.fk_user_paid,"; $sql.= " dp.libelle as libelle_paiement, dp.code as code_paiement"; // INNER JOIN paiement - $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." d LEFT JOIN ".MAIN_DB_PREFIX."c_paiement dp ON d.fk_c_paiement = dp.id"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id"; if ($ref) $sql.= " WHERE d.ref = '".$this->db->escape($ref)."'"; else $sql.= " WHERE d.rowid = ".$id; $sql.= $restrict; @@ -318,18 +335,18 @@ class ExpenseReport extends CommonObject if ($this->fk_user_validator > 0) $user_approver->fetch($this->fk_user_validator); $this->user_validator_infos = dolGetFirstLastname($user_approver->firstname, $user_approver->lastname); - $this->fk_c_expensereport_statuts = $obj->status; + $this->fk_statut = $obj->status; $this->status = $obj->status; $this->fk_c_paiement = $obj->fk_c_paiement; - if ($this->fk_c_expensereport_statuts==5 || $this->fk_c_expensereport_statuts==6) + if ($this->fk_statut==5 || $this->fk_statut==6) { $user_valid = new User($this->db); if ($this->fk_user_valid > 0) $user_valid->fetch($this->fk_user_valid); $this->user_valid_infos = dolGetFirstLastname($user_valid->firstname, $user_valid->lastname); } - if ($this->fk_c_expensereport_statuts==6) + if ($this->fk_statut==6) { $user_paid = new User($this->db); if ($this->fk_user_paid > 0) $user_paid->fetch($this->fk_user_paid); @@ -497,7 +514,7 @@ class ExpenseReport extends CommonObject $this->date_approve = $now; $this->status = 5; - $this->fk_c_expensereport_statuts = 5; + $this->fk_statut = 5; $this->fk_user_author = $user->id; $this->fk_user_valid = $user->id; @@ -567,7 +584,7 @@ class ExpenseReport extends CommonObject $objp = $db->fetch_object($result); - $sql2 = "SELECT d.rowid, d.fk_user_author, d.ref, d.fk_c_expensereport_statuts"; + $sql2 = "SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut"; $sql2.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; $sql2.= " WHERE d.rowid = '".$objp->fk_expensereport."'"; @@ -576,7 +593,7 @@ class ExpenseReport extends CommonObject $objp->fk_user_author = $obj->fk_user_author; $objp->ref = $obj->ref; - $objp->fk_c_expensereport_status = $obj->fk_c_expensereport_statuts; + $objp->fk_c_expensereport_status = $obj->fk_statut; $objp->rowid = $obj->rowid; $total_HT = $total_HT + $objp->total_ht; @@ -707,8 +724,8 @@ class ExpenseReport extends CommonObject $sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,'; $sql.= ' p.ref as ref_projet, p.title as title_projet'; $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as de'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON de.fk_c_type_fees = ctf.id'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet p ON de.fk_projet = p.rowid'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as p ON de.fk_projet = p.rowid'; $sql.= ' WHERE de.'.$this->fk_element.' = '.$this->id; dol_syslog('ExpenseReport::fetch_lines sql='.$sql, LOG_DEBUG); @@ -831,10 +848,10 @@ class ExpenseReport extends CommonObject $this->ref = strtoupper($user->login).$expld_car.$prefix.$this->ref.$expld_car.dol_print_date($this->date_debut,'%y%m%d'); } - if ($this->fk_c_expensereport_statuts != 2) + if ($this->fk_statut != 2) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref = '".$this->ref."', fk_c_expensereport_statuts = 2, fk_user_valid = ".$user->id.","; + $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$user->id.","; $sql.= " ref_number_int = ".$ref_number_int; $sql.= ' WHERE rowid = '.$this->id; @@ -877,10 +894,10 @@ class ExpenseReport extends CommonObject $this->date_debut = $this->db->jdate($objp->date_debut); - if ($this->fk_c_expensereport_statuts != 2) + if ($this->fk_statut != 2) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_c_expensereport_statuts = 2"; + $sql.= " SET fk_statut = 2"; $sql.= ' WHERE rowid = '.$this->id; dol_syslog(get_class($this)."::set_save_from_refuse sql=".$sql, LOG_DEBUG); @@ -913,10 +930,10 @@ class ExpenseReport extends CommonObject // date approval $this->date_approve = $this->db->idate($now); - if ($this->fk_c_expensereport_statuts != 5) + if ($this->fk_statut != 5) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref = '".$this->ref."', fk_c_expensereport_statuts = 5, fk_user_approve = ".$user->id.","; + $sql.= " SET ref = '".$this->ref."', fk_statut = 5, fk_user_approve = ".$user->id.","; $sql.= " date_approve='".$this->date_approve."'"; $sql.= ' WHERE rowid = '.$this->id; if ($this->db->query($sql)) @@ -946,17 +963,17 @@ class ExpenseReport extends CommonObject $now = dol_now(); // date de refus - if ($this->fk_c_expensereport_statuts != 99) + if ($this->fk_statut != 99) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref = '".$this->ref."', fk_c_expensereport_statuts = 99, fk_user_refuse = ".$user->id.","; + $sql.= " SET ref = '".$this->ref."', fk_statut = 99, fk_user_refuse = ".$user->id.","; $sql.= " date_refuse='".$this->db->idate($now)."',"; $sql.= " detail_refuse='".$this->db->escape($details)."'"; $sql.= " fk_user_approve=NULL,"; $sql.= ' WHERE rowid = '.$this->id; if ($this->db->query($sql)) { - $this->fk_c_expensereport_statuts = 99; + $this->fk_statut = 99; $this->fk_user_refuse = $user->id; $this->detail_refuse = $details; $this->date_refuse = $now; @@ -985,10 +1002,10 @@ class ExpenseReport extends CommonObject $now= dol_now(); $this->date_paiement = $this->db->idate($now); - if ($this->fk_c_expensereport_statuts != 6) + if ($this->fk_statut != 6) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_c_expensereport_statuts = 6, fk_user_paid = ".$user->id.","; + $sql.= " SET fk_statut = 6, fk_user_paid = ".$user->id.","; $sql.= " date_paiement='".$this->db->idate($this->date_paiement)."'"; $sql.= ' WHERE rowid = '.$this->id; @@ -1020,7 +1037,7 @@ class ExpenseReport extends CommonObject if ($this->fk_c_deplacement_statuts != 5) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_c_expensereport_statuts = 5"; + $sql.= " SET fk_statut = 5"; $sql.= ' WHERE rowid = '.$this->id; dol_syslog(get_class($this)."::set_unpaid sql=".$sql, LOG_DEBUG); @@ -1048,10 +1065,10 @@ class ExpenseReport extends CommonObject function set_cancel($user,$detail) { $this->date_cancel = $this->db->idate(gmmktime()); - if ($this->fk_c_expensereport_statuts != 4) + if ($this->fk_statut != 4) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_c_expensereport_statuts = 4, fk_user_cancel = ".$user->id; + $sql.= " SET fk_statut = 4, fk_user_cancel = ".$user->id; $sql.= ", date_cancel='".$this->date_cancel."'"; $sql.= " ,detail_cancel='".$this->db->escape($detail)."'"; $sql.= ' WHERE rowid = '.$this->id; @@ -1180,13 +1197,13 @@ class ExpenseReport extends CommonObject function updateline($rowid, $type_fees_id, $projet_id, $c_tva, $comments, $qty, $value_unit, $date, $expensereport_id) { - if ($this->fk_c_expensereport_statuts==0 || $this->fk_c_expensereport_statuts==99) + if ($this->fk_statut==0 || $this->fk_statut==99) { $this->db->begin(); // Select du taux de tva par rapport au code $sql = "SELECT t.taux as taux_tva"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_tva t"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t"; $sql.= " WHERE t.rowid = ".$c_tva; $result = $this->db->query($sql); $objp_tva = $this->db->fetch_object($result); @@ -1222,7 +1239,7 @@ class ExpenseReport extends CommonObject // Select des infos sur le type fees $sql = "SELECT c.code as code_type_fees, c.label as libelle_type_fees"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees c"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees as c"; $sql.= " WHERE c.id = ".$type_fees_id; $result = $this->db->query($sql); $objp_fees = $this->db->fetch_object($result); @@ -1231,7 +1248,7 @@ class ExpenseReport extends CommonObject // Select des informations du projet $sql = "SELECT p.ref as ref_projet, p.title as title_projet"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet p"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " WHERE p.rowid = ".$projet_id; $result = $this->db->query($sql); $objp_projet = $this->db->fetch_object($result); @@ -1403,6 +1420,39 @@ class ExpenseReport extends CommonObject return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); } + + /** + * List of types + * + * @param int $active Active or not + * @return array + */ + function listOfTypes($active=1) + { + global $langs; + $ret=array(); + $sql = "SELECT id, code, label"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees"; + $sql.= " WHERE active = ".$active; + dol_syslog(get_class($this)."::listOfTypes", LOG_DEBUG); + $result = $this->db->query($sql); + if ( $result ) + { + $num = $this->db->num_rows($result); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + $ret[$obj->code]=(($langs->trans($obj->code)!=$obj->code)?$langs->trans($obj->code):$obj->label); + $i++; + } + } + else + { + dol_print_error($this->db); + } + return $ret; + } } @@ -1460,9 +1510,9 @@ class ExpenseReportLine $sql.= ' fde.fk_c_tva as tva_taux, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det fde'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON fde.fk_c_type_fees=ctf.id'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet pjt ON fde.fk_projet=pjt.rowid'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid'; $sql.= ' WHERE fde.rowid = '.$rowid; $result = $this->db->query($sql); @@ -1643,7 +1693,7 @@ class ExpenseReportLine * @param int $useempty 1=Add empty line * @return string HTML select with sattus */ -function select_expensereport_statut($selected='',$htmlname='fk_c_expensereport_statuts',$useempty=1) +function select_expensereport_statut($selected='',$htmlname='fk_statut',$useempty=1) { global $db; @@ -1708,4 +1758,4 @@ function select_type_fees_id($selected='',$htmlname='type',$showempty=0) } } print '</select>'; -} +} \ No newline at end of file diff --git a/htdocs/expensereport/class/expensereportstats.class.php b/htdocs/expensereport/class/expensereportstats.class.php index 9536d59937d3eacad784edff35afb4a909e30f37..140e492972e7fff340df9bb02d7e8a98065f64a4 100644 --- a/htdocs/expensereport/class/expensereportstats.class.php +++ b/htdocs/expensereport/class/expensereportstats.class.php @@ -19,11 +19,11 @@ /** * \file htdocs/expensereport/class/expensereportstats.class.php - * \ingroup factures + * \ingroup ExpenseReport * \brief Fichier de la classe de gestion des stats des expensereport et notes de frais */ include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php'; -dol_include_once('/expensereport/class/expensereport.class.php'); +include_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; /** * Classe permettant la gestion des stats des expensereports et notes de frais @@ -59,7 +59,7 @@ class ExpenseReportStats extends Stats $this->from = MAIN_DB_PREFIX.$object->table_element; $this->field='total_ht'; - $this->where = " fk_c_expensereport_statuts > 0 and date_valid > '2000-01-01'"; + $this->where = " fk_statut > 0 and date_valid > '2000-01-01'"; //$this->where.= " AND entity = ".$conf->entity; if ($this->socid) { diff --git a/htdocs/expensereport/class/index.html b/htdocs/expensereport/class/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/expensereport/export_csv.php b/htdocs/expensereport/export_csv.php index 05036deaf7c092c0f7d3a8c8ce7d6375f205d55a..8228eb68532391bd6a0b1443432629a521efce17 100755 --- a/htdocs/expensereport/export_csv.php +++ b/htdocs/expensereport/export_csv.php @@ -21,8 +21,8 @@ */ require '../main.inc.php'; -require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php"); -dol_include_once("/expensereport/class/expensereport.class.php"); +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; $langs->load("users"); $langs->load("trips"); diff --git a/htdocs/expensereport/index.html b/htdocs/expensereport/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index 89469609e2a10cfbb09bebf0fe7bb78ff60fde88..62f5cbe89fccbdec199e539ed51adc668f8d1beb 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -25,8 +25,8 @@ */ require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php'; -dol_include_once("/expensereport/class/expensereport.class.php"); +require_once DOL_DOCUMENT_ROOT . '/compta/tva/class/tva.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; $langs->load("companies"); $langs->load("users"); @@ -111,8 +111,7 @@ print '<tr class="liste_titre">'; print '<td colspan="4">'.$langs->trans("Statistics").'</td>'; print "</tr>\n"; -//$listoftype=$tripandexpense_static->listOfTypes(); -$listoftype=$label; +$listoftype=$tripandexpense_static->listOfTypes(); foreach ($listoftype as $code => $label) { $dataseries[]=array('label'=>$label,'data'=>(isset($somme[$code])?(int) $somme[$code]:0)); @@ -143,7 +142,7 @@ $max=10; $langs->load("boxes"); -$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, d.rowid, d.date_debut as dated, d.date_fin as datef, d.date_create as dm, d.total_ht, d.total_ttc, d.fk_c_expensereport_statuts as fk_status"; +$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, d.rowid, d.date_debut as dated, d.date_fin as datef, d.date_create as dm, d.total_ht, d.total_ttc, d.fk_statut as fk_status"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d, ".MAIN_DB_PREFIX."user as u"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE u.rowid = d.fk_user_author"; @@ -187,8 +186,8 @@ if ($result) print '<tr '.$bc[$var].'>'; print '<td>'.$expensereportstatic->getNomUrl(1).'</td>'; print '<td>'.$userstatic->getNomUrl(1).'</td>'; - print '<td align="right">'.$obj->total_ht.'</td>'; - print '<td align="right">'.$obj->total_ttc.'</td>'; + print '<td align="right">'.price($obj->total_ht).'</td>'; + print '<td align="right">'.price($obj->total_ttc).'</td>'; print '<td align="right">'.dol_print_date($db->jdate($obj->dm),'day').'</td>'; print '<td align="right">'; //print $obj->libelle; diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index d6700ac26a2ba9255c7dd5b6f144667e567173d3..6d82b86e4af7e806cfbcac93993d584642bae0e0 100755 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -21,12 +21,13 @@ /** * \file htdocs/expensereport/index.php - * \brief Page liste des expensereports + * \brief list of expense reports */ require "../main.inc.php"; -dol_include_once("/expensereport/class/expensereport.class.php"); -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; $langs->load("companies"); $langs->load("users"); @@ -39,7 +40,7 @@ $result = restrictedArea($user, 'expensereport','',''); $search_ref = GETPOST('search_ref'); $search_user = GETPOST('search_user','int'); -$search_state = GETPOST('search_state','int'); +$search_status = GETPOST('search_status','int'); $month_start = GETPOST("month_start","int"); $year_start = GETPOST("year_start","int"); $month_end = GETPOST("month_end","int"); @@ -49,7 +50,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both { $search_ref=""; $search_user=""; - $search_state=""; + $search_status=""; $month_start=""; $year_start=""; $month_end=""; @@ -69,13 +70,12 @@ llxHeader('', $langs->trans("ListOfTrips")); $max_year = 5; $min_year = 5; -$sortorder = $_GET["sortorder"]; -$sortfield = $_GET["sortfield"]; -$page = $_GET["page"]; +$sortorder = GETPOST("sortorder"); +$sortfield = GETPOST("sortfield"); +$page = GETPOST("page"); if (!$sortorder) $sortorder="DESC"; if (!$sortfield) $sortfield="d.date_debut"; - if ($page == -1) { $page = 0 ; } @@ -85,79 +85,53 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -$sql = "SELECT d.rowid, d.ref, d.total_ht, d.total_tva, d.total_ttc, d.fk_c_expensereport_statuts as status,"; +$sql = "SELECT d.rowid, d.ref, d.total_ht, d.total_tva, d.total_ttc, d.fk_statut as status,"; $sql.= " d.date_debut, d.date_fin,"; $sql.= " u.rowid as id_user, u.firstname, u.lastname"; -$sql.= " FROM ".MAIN_DB_PREFIX."expensereport d\n"; -$sql.= " INNER JOIN ".MAIN_DB_PREFIX."user u ON d.fk_user_author = u.rowid\n"; - +$sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; +$sql.= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON d.fk_user_author = u.rowid"; - -// WHERE +// Where if(!empty($search_ref)){ - $sql.= " WHERE d.ref LIKE '%".$db->escape($search_ref)."%'\n"; + $sql.= " WHERE d.ref LIKE '%".$db->escape($search_ref)."%'"; }else{ - $sql.= " WHERE 1 = 1\n"; + $sql.= " WHERE 1 = 1"; } -// DATE START -if ($month_start > 0) { - if ($year_start > 0) { - if($month_end > 0) { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; - $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; - $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; - } - } else { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; - $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; - } - } - } else { - $sql.= " AND date_format(d.date_debut, '%m') >= '$month_start'"; - } -} else { - if ($year_start > 0) { - if($month_end > 0) { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; - } - } else { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - } - } - } else { - if($month_end > 0) { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; - } - } else { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; - } - } - } +// Date Start +if ($month_start > 0) +{ + if ($year_start > 0 && empty($day)) + $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_get_first_day($year_start,$month_start,false))."' AND '".$db->idate(dol_get_last_day($year_start,$month_start,false))."'"; + else if ($year_start > 0 && ! empty($day)) + $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_start, $day, $year_start))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_start, $day, $year_start))."'"; + else + $sql.= " AND date_format(d.date_debut, '%m') = '".$month_start."'"; +} +else if ($year_start > 0) +{ + $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_get_first_day($year_start,1,false))."' AND '".$db->idate(dol_get_last_day($year_start,12,false))."'"; } -if (!empty($search_user) && $search_user > 0) $sql.= " AND d.fk_user_author = ".$search_user."\n"; -if($search_state != '') $sql.= " AND d.fk_c_expensereport_statuts = '$search_state'\n"; +// Date Start +if ($month_end > 0) +{ + if ($year_end > 0 && empty($day)) + $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_get_first_day($year_end,$month_end,false))."' AND '".$db->idate(dol_get_last_day($year_end,$month_end,false))."'"; + else if ($year_end > 0 && ! empty($day)) + $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_end, $day, $year_end))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_end, $day, $year_end))."'"; + else + $sql.= " AND date_format(d.date_fin, '%m') = '".$month_end."'"; +} +else if ($year_end > 0) +{ + $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_get_first_day($year_end,1,false))."' AND '".$db->idate(dol_get_last_day($year_end,12,false))."'"; +} +// User +if ($search_name) +{ + $sql .= natural_search('u.lastname', $search_name); +} +// Status +if($search_status != '') $sql.= " AND d.fk_statut = '".$search_status."'"; // RESTRICT RIGHTS if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)) @@ -219,17 +193,13 @@ if ($resql) print '<td class="liste_titre"> </td>'; } - print '<td class="liste_titre"> </td>'; - print '<td class="liste_titre"> </td>'; - - print '<td class="liste_titre" align="right">'; - print "</td>"; + print '<td class="liste_titre"> </td>'; // Status print '<td class="liste_titre" align="right">'; - select_expensereport_statut($search_state,'search_state'); + select_expensereport_statut($search_status,'search_status'); print '</td>'; print '<td class="liste_titre" align="right">'; @@ -257,10 +227,6 @@ if ($resql) print '<td align="center">'.($objp->date_debut > 0 ? dol_print_date($objp->date_debut, 'day') : '').'</td>'; print '<td align="center">'.($objp->date_fin > 0 ? dol_print_date($objp->date_fin, 'day') : '').'</td>'; print '<td align="left"><a href="'.DOL_URL_ROOT.'/user/card.php?id='.$objp->id_user.'">'.img_object($langs->trans("ShowUser"),"user").' '.dolGetFirstLastname($objp->firstname, $objp->lastname).'</a></td>'; - /*print '<td align="right">'.price($objp->total_tva, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; - print '<td align="right">'.price($objp->total_ht, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; - print '<td align="right">'.price($objp->total_ttc, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; - */ print '<td align="right">'.price($objp->total_ht).'</td>'; print '<td align="right">'.price($objp->total_tva).'</td>'; print '<td align="right">'.price($objp->total_ttc).'</td>'; @@ -281,11 +247,7 @@ if ($resql) print '<tr class="liste_total">'; print '<td colspan="4">'.$langs->trans("Total").'</td>'; - /* - print '<td style="text-align:right;">'.price($total_total_tva, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; - print '<td style="text-align:right;">'.price($total_total_ht, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; - print '<td style="text-align:right;">'.price($total_total_ttc, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; - */ + print '<td style="text-align:right;">'.$total_total_ht.'</td>'; print '<td style="text-align:right;">'.$total_total_tva.'</td>'; print '<td style="text-align:right;">'.$total_total_ttc.'</td>'; diff --git a/htdocs/expensereport/stats/index.html b/htdocs/expensereport/stats/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/expensereport/synchro_compta.php b/htdocs/expensereport/synchro_compta.php index b8f7760e409c00240f4d4f8b5af46668737170a3..58fcbaee30154c9bd92724a06e29733385c7356e 100755 --- a/htdocs/expensereport/synchro_compta.php +++ b/htdocs/expensereport/synchro_compta.php @@ -16,8 +16,8 @@ */ require '../main.inc.php'; -require_once(DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'); -dol_include_once("/expensereport/class/expensereport.class.php"); +require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; $langs->load("companies"); $langs->load("users"); @@ -49,12 +49,12 @@ if ($_GET["action"] == 'confirm_ndf_to_account' && $_GET["confirm"] == "yes"): $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, $cat1, $user); if ($insertid > 0): - $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport as d"; $sql.= " SET integration_compta = 1, fk_bank_account = $idAccount"; $sql.= " WHERE rowid = $idTrip"; $resql=$db->query($sql); if($result): - Header("Location: synchro_compta.php?account=".$idAccount); + Header("Location: ".$_SERVER["PHP_SELF"]."?account=".$idAccount); exit; else: dol_print_error($db); @@ -75,12 +75,12 @@ if ($_GET["action"] == 'confirm_account_to_ndf' && $_GET["confirm"] == "yes"): $sql.= " WHERE label LIKE '%".$expensereport->ref."%'"; $resql=$db->query($sql); if ($resql > 0): - $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport as d"; $sql.= " SET integration_compta = 0, fk_bank_account = 0"; $sql.= " WHERE rowid = $idTrip"; $resql=$db->query($sql); if($result): - Header("Location: synchro_compta.php?account=".$idAccount); + Header("Location: ".$_SERVER["PHP_SELF"]."?account=".$idAccount); exit; else: dol_print_error($db); @@ -110,13 +110,13 @@ dol_fiche_head(''); if ($_GET["action"] == 'ndfTOaccount'): $idTrip = $_GET['idTrip']; - $ret=$html->form_confirm("synchro_compta.php?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("ndfToAccount"),$langs->trans("ConfirmNdfToAccount"),"confirm_ndf_to_account","","",1); + $ret=$html->form_confirm($_SERVER["PHP_SELF"]."?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("ndfToAccount"),$langs->trans("ConfirmNdfToAccount"),"confirm_ndf_to_account","","",1); if ($ret == 'html') print '<br />'; endif; if ($_GET["action"] == 'accountTOndf'): $idTrip = $_GET['idTrip']; - $ret=$html->form_confirm("synchro_compta.php?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("AccountToNdf"),$langs->trans("ConfirmAccountToNdf"),"confirm_account_to_ndf","","",1); + $ret=$html->form_confirm($_SERVER["PHP_SELF"]."?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("AccountToNdf"),$langs->trans("ConfirmAccountToNdf"),"confirm_account_to_ndf","","",1); if ($ret == 'html') print '<br />'; endif; @@ -136,11 +136,11 @@ else: print ' <input type="submit" class="button" value="'.$langs->trans("ViewAccountSynch").'">'; print "</form>"; - $sql = "SELECT d.fk_bank_account, d.ref, d.rowid, d.date_valid, d.fk_user_author, d.total_ttc, d.integration_compta, d.fk_c_expensereport_statuts"; + $sql = "SELECT d.fk_bank_account, d.ref, d.rowid, d.date_valid, d.fk_user_author, d.total_ttc, d.integration_compta, d.fk_statut"; $sql.= " ,CONCAT(u.firstname,' ',u.lastname) as declarant_NDF"; - $sql.= " FROM ".MAIN_DB_PREFIX."expensereport d"; - $sql.= " INNER JOIN ".MAIN_DB_PREFIX."user u ON d.fk_user_author = u.rowid"; - $sql.= " WHERE d.fk_c_expensereport_statuts = 6"; + $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; + $sql.= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON d.fk_user_author = u.rowid"; + $sql.= " WHERE d.fk_statut = 6"; $sql.= " ORDER BY d.date_valid DESC"; $resql=$db->query($sql); @@ -200,7 +200,7 @@ else: print "</table>"; else: - print '<div class="error">'.$langs->trans("AucuneTripToSynch").'</div>'; + print '<div class="error">'.$langs->trans("NoTripToSync").'</div>'; endif; $db->free($resql); diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 6101aa7e17dd8ff761caaf9ff4b183b03a1ca9b6..41d06bebf4396cd46ebbdcb3335b9aefb5f1556b 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1947,28 +1947,28 @@ elseif (! empty($object->id)) // Ligne de 3 colonnes print '<tr><td>'.$langs->trans("AmountHT").'</td>'; - print '<td align="right"><b>'.price($object->total_ht).'</b></td>'; - print '<td>'.$langs->trans("Currency".$conf->currency).'</td></tr>'; + print '<td colspan="2">'.price($object->total_ht,'',$langs,1,-1,-1,$conf->currency).'</td>'; + print '</tr>'; - print '<tr><td>'.$langs->trans("AmountVAT").'</td><td align="right">'.price($object->total_tva).'</td>'; - print '<td>'.$langs->trans("Currency".$conf->currency).'</td></tr>'; + print '<tr><td>'.$langs->trans("AmountVAT").'</td><td colspan="2">'.price($object->total_tva,'',$langs,1,-1,-1,$conf->currency).'</td>'; + print '</tr>'; // Amount Local Taxes if ($mysoc->localtax1_assuj=="1" || $object->total_localtax1 != 0) //Localtax1 { print '<tr><td>'.$langs->transcountry("AmountLT1",$mysoc->country_code).'</td>'; - print '<td align="right">'.price($object->total_localtax1).'</td>'; - print '<td>'.$langs->trans("Currency".$conf->currency).'</td></tr>'; + print '<td colspan="2">'.price($object->total_localtax1,'',$langs,1,-1,-1,$conf->currency).'</td>'; + print '</tr>'; } if ($mysoc->localtax2_assuj=="1" || $object->total_localtax2 != 0) //Localtax2 { print '<tr><td>'.$langs->transcountry("AmountLT2",$mysoc->country_code).'</td>'; - print '<td align="right">'.price($object->total_localtax2).'</td>'; - print '<td>'.$langs->trans("Currency".$conf->currency).'</td></tr>'; + print '<td colspan="2">'.price($object->total_localtax2,'',$langs,1,-1,-1,$conf->currency).'</td>'; + print '</tr>'; } - print '<tr><td>'.$langs->trans("AmountTTC").'</td><td align="right">'.price($object->total_ttc).'</td>'; - print '<td>'.$langs->trans("Currency".$conf->currency).'</td></tr>'; + print '<tr><td>'.$langs->trans("AmountTTC").'</td><td colspan="2">'.price($object->total_ttc,'',$langs,1,-1,-1,$conf->currency).'</td>'; + print '</tr>'; print "</table><br>"; @@ -2610,7 +2610,7 @@ elseif (! empty($object->id)) print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen">'.$langs->trans("ReOpen").'</a>'; } } - + // Create bill if (! empty($conf->fournisseur->enabled) && $object->statut >= 2) // 2 means accepted { diff --git a/htdocs/install/etape1.php b/htdocs/install/etape1.php index 4f31a728a1d743f04588895d0dd6a98abeb18345..f7b81e1da663ea78b726cb07f7db5fa7cff49d2f 100644 --- a/htdocs/install/etape1.php +++ b/htdocs/install/etape1.php @@ -86,12 +86,15 @@ if (! is_writable($conffile)) // Check parameters +$is_sqlite = false; if (empty($db_type)) { print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("DatabaseType")).'</div>'; $error++; +} else { + $is_sqlite = ($db_type === 'sqlite' || $db_type === 'sqlite3' ); } -if (empty($db_host)) +if (empty($db_host) && ! $is_sqlite) { print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Server")).'</div>'; $error++; @@ -101,7 +104,7 @@ if (empty($db_name)) print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("DatabaseName")).'</div>'; $error++; } -if (empty($db_user)) +if (empty($db_user) && ! $is_sqlite) { print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Login")).'</div>'; $error++; diff --git a/htdocs/install/etape2.php b/htdocs/install/etape2.php index 1f6c5244d84a693abc3db1f074a03bbf587ffa08..8c0e3f8ab5c8a4ce14a285de519da1e2cc3f7201 100644 --- a/htdocs/install/etape2.php +++ b/htdocs/install/etape2.php @@ -51,6 +51,9 @@ if ($dolibarr_main_db_type == "mysql") $choix=1; if ($dolibarr_main_db_type == "mysqli") $choix=1; if ($dolibarr_main_db_type == "pgsql") $choix=2; if ($dolibarr_main_db_type == "mssql") $choix=3; +if ($dolibarr_main_db_type == "sqlite") $choix=4; +if ($dolibarr_main_db_type == "sqlite3") $choix=5; + //if (empty($choix)) dol_print_error('','Database type '.$dolibarr_main_db_type.' not supported into etape2.php page'); // Now we load forced value from install.forced.php file. @@ -411,6 +414,7 @@ if ($action == "set") if ($choix==1) $dir = "mysql/functions/"; elseif ($choix==2) $dir = "pgsql/functions/"; elseif ($choix==3) $dir = "mssql/functions/"; + elseif ($choix==4) { $dir = "sqlite3/functions/"; } // Creation donnees $file = "functions.sql"; diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php index 2c6a5730100f7c5d05bab417dc5d26c17fdc17e3..5dce328d04c2d93b4169ffda452e86935db86eb6 100644 --- a/htdocs/install/fileconf.php +++ b/htdocs/install/fileconf.php @@ -306,7 +306,7 @@ if (! empty($force_install_message)) $class='DoliDB'.ucfirst($type); include_once $dir."/".$file; - if ($type == 'sqlite') continue; // We hide sqlite because support can't be complete unti sqlit does not manage foreign key creation after table creation + if ($type == 'sqlite') continue; // We hide sqlite because support can't be complete until sqlite does not manage foreign key creation after table creation // Version min of database $versionbasemin=explode('.',$class::VERSIONMIN); @@ -320,7 +320,8 @@ if (! empty($force_install_message)) if ($type=='mysqli') { $testfunction='mysqli_connect'; $testclass=''; } if ($type=='pgsql') { $testfunction='pg_connect'; $testclass=''; } if ($type=='mssql') { $testfunction='mssql_connect'; $testclass=''; } - if ($type=='sqlite') { $testfunction=''; $testclass='PDO'; } + if ($type=='sqlite') { $testfunction=''; $testclass='PDO'; } + if ($type=='sqlite3') { $testfunction=''; $testclass='SQLite3'; } $option.='<option value="'.$type.'"'.($defaultype == $type?' selected="selected"':''); if ($testfunction && ! function_exists($testfunction)) $option.=' disabled="disabled"'; if ($testclass && ! class_exists($testclass)) $option.=' disabled="disabled"'; @@ -330,6 +331,7 @@ if (! empty($force_install_message)) // Experimental if ($type=='mssql') $option.=' '.$langs->trans("Experimental"); elseif ($type=='sqlite') $option.=' '.$langs->trans("Experimental"); + elseif ($type=='sqlite3') $option.=' '.$langs->trans("Experimental"); // No available elseif (! function_exists($testfunction)) $option.=' - '.$langs->trans("FunctionNotAvailableInThisPHP"); $option.='</option>'; @@ -479,7 +481,7 @@ if (! empty($force_install_message)) jQuery(document).ready(function() { jQuery("#db_type").change(function() { - if (jQuery("#db_type").val()=='sqlite') { jQuery(".hidesqlite").hide(); } + if (jQuery("#db_type").val()=='sqlite' || jQuery("#db_type").val()=='sqlite3') { jQuery(".hidesqlite").hide(); } else { jQuery(".hidesqlite").show(); } }); diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index 03736b088fc507e04d1011f3a20375fb782372ec..65273632998ea75adfc64ab7e84dd872bdfbba56 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -20,6 +20,7 @@ ALTER TABLE llx_extrafields ADD COLUMN perms varchar(255) after fieldrequired; +ALTER TABLE llx_extrafields ADD COLUMN list integer DEFAULT 0 after perms; ALTER TABLE llx_payment_salary ADD COLUMN salary real after datev; @@ -161,7 +162,7 @@ CREATE TABLE llx_expensereport ( fk_user_refuse integer DEFAULT NULL, fk_user_cancel integer DEFAULT NULL, fk_user_paid integer DEFAULT NULL, - fk_c_expensereport_statuts integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé + fk_statut integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé fk_c_paiement integer DEFAULT NULL, note_public text, note_private text, diff --git a/htdocs/install/mysql/tables/llx_expensereport.sql b/htdocs/install/mysql/tables/llx_expensereport.sql index e60be7251a541ba2931a314c5f93bc13ae177d98..657d8f9e278b9624b7de48fb1d07d38c6fbf9c73 100755 --- a/htdocs/install/mysql/tables/llx_expensereport.sql +++ b/htdocs/install/mysql/tables/llx_expensereport.sql @@ -44,7 +44,7 @@ CREATE TABLE llx_expensereport ( fk_user_refuse integer DEFAULT NULL, fk_user_cancel integer DEFAULT NULL, fk_user_paid integer DEFAULT NULL, - fk_c_expensereport_statuts integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé + fk_statut integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé fk_c_paiement integer DEFAULT NULL, note_public text, note_private text, diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql index 112711255085d50ce724d48db8b8888779004300..21610d07c0efd35581611fca4f5746e0bf097c2d 100644 --- a/htdocs/install/mysql/tables/llx_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_extrafields.sql @@ -32,5 +32,6 @@ create table llx_extrafields perms varchar(255), pos integer DEFAULT 0, alwayseditable integer DEFAULT 0, - param text + param text, + list integer DEFAULT 0 )ENGINE=innodb; diff --git a/htdocs/install/sqlite3/functions/functions.sql b/htdocs/install/sqlite3/functions/functions.sql new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/install/sqlite3/index.html b/htdocs/install/sqlite3/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 85e8406d70822d758a045a0827ecbe43c9731417..3075d128066ae159588227aeb9f951d23a833326 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -553,11 +553,11 @@ foreach ($listofreferent as $key => $value) { if ($key == 'order_supplier' && ! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande->creer) { - print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?socid='.$object->thirdparty->id.'&action=create&origin='.$object->element.'&originid='.$object->id.'">'.$langs->trans("AddSupplierInvoice").'</a>'; + print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?socid='.$project->thirdparty->id.'&action=create&origin='.$project->element.'&originid='.$project->id.'">'.$langs->trans("AddSupplierOrder").'</a>'; } if ($key == 'invoice_supplier' && ! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->creer) { - print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?socid='.$object->thirdparty->id.'&action=create&origin='.$object->element.'&originid='.$object->id.'">'.$langs->trans("AddSupplierOrder").'</a>'; + print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?socid='.$project->thirdparty->id.'&action=create&origin='.$project->element.'&originid='.$project->id.'">'.$langs->trans("AddSupplierInvoice").'</a>'; } } } diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 37e646d6b88084bdb469c535085b42e58fc7034b..255ab6a05a67dcd211fc1dfb0555501a3fbc5aec 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -49,6 +49,10 @@ class CompanyBankAccount extends Account var $owner_address; var $default_rib; + var $datec; + var $datem; + + /** * Constructor * @@ -174,7 +178,7 @@ class CompanyBankAccount extends Account { if (empty($id) && empty($socid)) return -1; - $sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation, proprio, owner_address, default_rib, label"; + $sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation, proprio, owner_address, default_rib, label, datec, tms as datem"; $sql.= " FROM ".MAIN_DB_PREFIX."societe_rib"; if ($id) $sql.= " WHERE rowid = ".$id; if ($socid) $sql.= " WHERE fk_soc = ".$socid." AND default_rib = 1"; @@ -200,6 +204,8 @@ class CompanyBankAccount extends Account $this->owner_address = $obj->owner_address; $this->label = $obj->label; $this->default_rib = $obj->default_rib; + $this->datec = $this->db->jdate($obj->datec); + $this->datem = $this->db->jdate($obj->datem); } $this->db->free($resql); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ea08019853ea67d3039dc2f1c9f09aef9e3fa9d4..ee81df97889dd14d7a70cde214430c3727f2f0f1 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -968,7 +968,7 @@ class Societe extends CommonObject * @param string $idprof2 Prof id 2 of third party (Warning, this can return several records) * @param string $idprof3 Prof id 3 of third party (Warning, this can return several records) * @param string $idprof4 Prof id 4 of third party (Warning, this can return several records) - * @return int >0 if OK, <0 if KO or if two records found for same ref or idprof. + * @return int >0 if OK, <0 if KO or if two records found for same ref or idprof, 0 if not found. */ function fetch($rowid, $ref='', $ref_ext='', $ref_int='', $idprof1='',$idprof2='',$idprof3='',$idprof4='') { @@ -1025,7 +1025,7 @@ class Societe extends CommonObject { $this->error='Fetch several records found for ref='.$ref; dol_syslog($this->error, LOG_ERR); - $result = -1; + $result = -2; } if ($num) { @@ -1150,17 +1150,15 @@ class Societe extends CommonObject $this->fetch_optionals($this->id,$extralabels); } else - { - $this->error='Fetch no third party found for id='.$rowid; - dol_syslog($this->error, LOG_ERR); - $result = -2; + { + $result = 0; } $this->db->free($resql); } else - { - $this->error=$this->db->error(); + { + $this->error=$this->db->lasterror(); $result = -3; } @@ -1180,12 +1178,21 @@ class Societe extends CommonObject * @param boolean $case Case sensitive (true/false) * @param boolean $similar Add test if string inside name into database, or name into database inside string. Do not use this: Not compatible with other database. * @param string $clause Clause for filters - * @return array Array of thirdparties object + * @return array|int <0 if KO, array of thirdparties object if OK */ function searchByName($name, $type='0', $filters = array(), $exact = false, $case = false, $similar = false, $clause = 'AND') { $thirdparties = array(); + dol_syslog("searchByName name=".$name." type=".$type." exact=".$exact); + + // Check parameter + if (empty($name)) + { + $this->errors[]='ErrorBadValueForParameter'; + return -1; + } + // Generation requete recherche $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe"; $sql.= " WHERE entity IN (".getEntity('category',1).")"; @@ -1264,7 +1271,7 @@ class Societe extends CommonObject } else { - $this->error=$this->db->error().' sql='.$sql; + $this->error=$this->db->lasterror(); return -1; } } diff --git a/htdocs/societe/rib.php b/htdocs/societe/rib.php index 2a21f6cdc87336e5cb6ae703820fb5b9cf962b63..dd2e0e4d21b1ee2a77668e394155044e580a0ffb 100644 --- a/htdocs/societe/rib.php +++ b/htdocs/societe/rib.php @@ -29,6 +29,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; $langs->load("companies"); $langs->load("commercial"); @@ -191,6 +192,7 @@ if ($action == 'confirm_delete' && $_GET['confirm'] == 'yes') */ $form = new Form($db); +$prelevement = new BonPrelevement($db); llxHeader(); @@ -336,11 +338,11 @@ if ($socid && $action != 'edit' && $action != "create") print "<br>"; - + /* * List of bank accounts */ - + print_titre($langs->trans("AllRIB")); $rib_list = $soc->get_all_rib(); @@ -355,6 +357,10 @@ if ($socid && $action != 'edit' && $action != "create") print_liste_field_titre($langs->trans("RIB")); print_liste_field_titre($langs->trans("IBAN")); print_liste_field_titre($langs->trans("BIC")); + if (! empty($conf->prelevement->enabled)) + { + print '<td>RUM</td>'; + } print_liste_field_titre($langs->trans("DefaultRIB"), '', '', '', '', 'align="center"'); print '<td width="40"></td>'; print '</tr>'; @@ -372,6 +378,12 @@ if ($socid && $action != 'edit' && $action != "create") print '<td>'.$rib->iban.'</td>'; // BIC print '<td>'.$rib->bic.'</td>'; + + if (! empty($conf->prelevement->enabled)) + { + print '<td>'.$prelevement->buildRumNumber($soc->code_client, $rib->datec, $rib->id).'</td>'; + } + // Default print '<td align="center" width="70">'; if (!$rib->default_rib) {