diff --git a/COPYRIGHT b/COPYRIGHT index b8cf93e595a..4e43541fa60 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -40,7 +40,7 @@ jQuery blockUI 2.70.0 GPL and MIT License Yes jQuery Colorpicker 1.1 MIT License Yes JS library for color picker for a defined list of colors jQuery DataTables 1.9.4 BSD Yes JS library for tables output jQuery FileUpload 5.0.3 GPL and MIT License Yes JS library to upload files -jQuery Flot 0.7 MIT License Yes JS library to build graph +jQuery Flot 0.8.3 MIT License Yes JS library to build graph jQuery JCrop 0.9.8 GPL and MIT License Yes JS library plugin Crop (to crop images) jQuery Jeditable 1.7.1 GPL and MIT License Yes JS library plugin jeditable (to edit in place) jQuery jNotify 1.1.00 Apache Software License 2.0 Yes JS library plugin jNotify (to use ajax popups) diff --git a/ChangeLog b/ChangeLog index e3d40f3a04c..2510764c349 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,7 +12,7 @@ Upgrading to any other version or any other database system is abolutely require make a Dolibarr upgrade. -***** ChangeLog for 4.0 compared to 3.9.* ***** +***** ChangeLog for 4.0.0 compared to 3.9.* ***** For users: NEW: Add reccuring invoice feature and automatic generation of invoices. diff --git a/build/exe/doliwamp/doliwamp.iss b/build/exe/doliwamp/doliwamp.iss index f302c9a2b57..e4cfc326422 100644 --- a/build/exe/doliwamp/doliwamp.iss +++ b/build/exe/doliwamp/doliwamp.iss @@ -101,6 +101,7 @@ Source: "build\exe\doliwamp\UsedPort.exe"; DestDir: "{app}\"; Flags: ignoreversi ; Put here path of Wampserver applications ; Value OK: apache 2.2.6, php 5.2.5 (5.2.11, 5.3.0 and 5.3.1 fails if php_exif, php_pgsql, php_zip is on), mysql 5.0.45 or 5.1.36 ; Value OK: apache 2.2.11, php 5.3.0 (if no php_exif, php_pgsql, php_zip), mysql 5.0.45 or 5.1.36 +; Value ???: apache 2.4.19, php 5.5.12, mysql 5.6.17 Source: "C:\Program Files\Wamp\apps\phpmyadmin4.1.14\*.*"; DestDir: "{app}\apps\phpmyadmin4.1.14"; Flags: ignoreversion recursesubdirs; Excludes: "config.inc.php,wampserver.conf,*.log,*_log,darkblue_orange" Source: "C:\Program Files\Wamp\bin\apache\apache2.4.9\*.*"; DestDir: "{app}\bin\apache\apache2.4.9"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log" Source: "C:\Program Files\Wamp\bin\php\php5.5.12\*.*"; DestDir: "{app}\bin\php\php5.5.12"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,phpForApache.ini,wampserver.conf,*.log,*_log" @@ -109,7 +110,7 @@ Source: "C:\Program Files\Wamp\bin\mysql\mysql5.6.17\*.*"; DestDir: "{app}\bin\m Source: "build\exe\doliwamp\mysql\*.*"; DestDir: "{app}\bin\mysql\data\mysql"; Flags: onlyifdoesntexist ignoreversion recursesubdirs; Excludes: ".gitignore,.project,CVS\*,Thumbs.db" ; Dolibarr Source: "htdocs\*.*"; DestDir: "{app}\www\dolibarr\htdocs"; Flags: ignoreversion recursesubdirs; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,custom\*,custom2\*,documents\*,includes\ckeditor\_source\*,includes\savant\*,includes\phpmailer\*,jquery\plugins\template\*,nltechno*\*,PHPExcel\Shared\PDF\*,PHPExcel\Shared\PCLZip\*,tcpdf\fonts\dejavu-fonts-ttf-2.33\*,tcpdf\fonts\freefont-20100919\*,tcpdf\fonts\utils\*,*\conf.php,*\conf.php.mysql,*\conf.php.old,*\conf.php.postgres,*\conf.php.sav,*\install.forced.php" -Source: "dev\*.*"; DestDir: "{app}\www\dolibarr\dev"; Flags: ignoreversion recursesubdirs; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,dbmodel\*,fpdf\*,initdata\*,iso-normes\*,licence\*,phpcheckstyle\*,phpunit\*,samples\*,test\*,uml\*,vagrant\*,xdebug\*" +Source: "dev\*.*"; DestDir: "{app}\www\dolibarr\dev"; Flags: ignoreversion recursesubdirs; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,dbmodel\*,fpdf\*,initdata\*,initdemo\*,iso-normes\*,licence\*,phpcheckstyle\*,phpunit\*,samples\*,test\*,uml\*,vagrant\*,xdebug\*" Source: "doc\*.*"; DestDir: "{app}\www\dolibarr\doc"; Flags: ignoreversion recursesubdirs; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,wiki\*,plaquette\*,dev\*,images\dolibarr_screenshot2.png,images\dolibarr_screenshot3.png,images\dolibarr_screenshot4.png,images\dolibarr_screenshot5.png,images\dolibarr_screenshot6.png,images\dolibarr_screenshot7.png,images\dolibarr_screenshot8.png,images\dolibarr_screenshot9.png,images\dolibarr_screenshot10.png,images\dolibarr_screenshot11.png,images\dolibarr_screenshot12.png" Source: "scripts\*.*"; DestDir: "{app}\www\dolibarr\scripts"; Flags: ignoreversion recursesubdirs; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,product\materiel.net.php,product\import-product.php" Source: "*.*"; DestDir: "{app}\www\dolibarr"; Flags: ignoreversion; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,default.properties,install.lock" diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 45c8e0a6f42..b6c86a7a119 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -53,7 +53,7 @@ if (-d "/usr/src/RPM") { $RPMDIR="/usr/src/RPM"; } # mandrake use vars qw/ $REVISION $VERSION /; -$VERSION="3.3"; +$VERSION="4.0"; @@ -356,6 +356,7 @@ if ($nboftargetok) { # Test that the ChangeLog is ok $TMPBUILDTOCHECKCHANGELOG=$BUILD; $TMPBUILDTOCHECKCHANGELOG =~ s/\-rc\d*//; + $TMPBUILDTOCHECKCHANGELOG =~ s/\-beta\d*//; print "Check if ChangeLog is ok for version $MAJOR.$MINOR\.$TMPBUILDTOCHECKCHANGELOG\n"; $ret=`grep "ChangeLog for $MAJOR.$MINOR\.$TMPBUILDTOCHECKCHANGELOG" "$SOURCE/ChangeLog" 2>&1`; if (! $ret) @@ -458,6 +459,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/dev/codetemplates`; $ret=`rm -fr $BUILDROOT/$PROJECT/dev/dbmodel`; $ret=`rm -fr $BUILDROOT/$PROJECT/dev/initdata`; + $ret=`rm -fr $BUILDROOT/$PROJECT/dev/initdemo`; $ret=`rm -fr $BUILDROOT/$PROJECT/dev/iso-normes`; $ret=`rm -fr $BUILDROOT/$PROJECT/dev/ldap`; $ret=`rm -fr $BUILDROOT/$PROJECT/dev/licence`; @@ -1121,7 +1123,7 @@ if ($nboftargetok) { { if ($CHOOSEDPUBLISH{$target} < 0) { next; } - print "\nList of files to publish\n"; + print "\nList of files to publish (BUILD=$BUILD)\n"; %filestoscansf=( "$DESTI/package_rpm_generic/$FILENAMERPM"=>'Dolibarr installer for Fedora-Redhat-Mandriva-Opensuse (DoliRpm)', "$DESTI/package_debian-ubuntu/${FILENAMEDEB}_all.deb"=>'Dolibarr installer for Debian-Ubuntu (DoliDeb)', @@ -1136,6 +1138,22 @@ if ($nboftargetok) { "$DESTI/standard/$FILENAMETGZ.tgz"=>'standard', "$DESTI/standard/$FILENAMETGZ.zip"=>'standard' ); + if ($target eq 'ASSO' && $BUILD =~ /[a-z]/i) { # Not stable + %filestoscansf=( + "$DESTI/$FILENAMERPM"=>'Dolibarr installer for Fedora-Redhat-Mandriva-Opensuse (DoliRpm)', + "$DESTI/${FILENAMEDEB}_all.deb"=>'Dolibarr installer for Debian-Ubuntu (DoliDeb)', + "$DESTI/$FILENAMEEXEDOLIWAMP.exe"=>'Dolibarr installer for Windows (DoliWamp)', + "$DESTI/$FILENAMETGZ.tgz"=>'Dolibarr ERP-CRM', + "$DESTI/$FILENAMETGZ.zip"=>'Dolibarr ERP-CRM' + ); + %filestoscanstableasso=( + "$DESTI/$FILENAMERPM"=>'', + "$DESTI/${FILENAMEDEB}_all.deb"=>'', + "$DESTI/$FILENAMEEXEDOLIWAMP.exe"=>'', + "$DESTI/$FILENAMETGZ.tgz"=>'', + "$DESTI/$FILENAMETGZ.zip"=>'' + ); + } use POSIX qw/strftime/; foreach my $file (sort keys %filestoscansf) diff --git a/build/rpm/dolibarr_fedora.spec b/build/rpm/dolibarr_fedora.spec index 0cd72f99cdd..4ad1441104d 100755 --- a/build/rpm/dolibarr_fedora.spec +++ b/build/rpm/dolibarr_fedora.spec @@ -192,6 +192,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/loan %_datadir/dolibarr/htdocs/mailmanspip %_datadir/dolibarr/htdocs/margin +%_datadir/dolibarr/htdocs/multicurrency %_datadir/dolibarr/htdocs/opensurvey %_datadir/dolibarr/htdocs/paybox %_datadir/dolibarr/htdocs/paypal @@ -206,6 +207,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/theme %_datadir/dolibarr/htdocs/user %_datadir/dolibarr/htdocs/webservices +%_datadir/dolibarr/htdocs/websites %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec index 043088bf5d6..f20b2047225 100755 --- a/build/rpm/dolibarr_generic.spec +++ b/build/rpm/dolibarr_generic.spec @@ -272,6 +272,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/loan %_datadir/dolibarr/htdocs/mailmanspip %_datadir/dolibarr/htdocs/margin +%_datadir/dolibarr/htdocs/multicurrency %_datadir/dolibarr/htdocs/opensurvey %_datadir/dolibarr/htdocs/paybox %_datadir/dolibarr/htdocs/paypal @@ -286,6 +287,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/theme %_datadir/dolibarr/htdocs/user %_datadir/dolibarr/htdocs/webservices +%_datadir/dolibarr/htdocs/websites %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_mandriva.spec b/build/rpm/dolibarr_mandriva.spec index 3f439bb4a9a..ca836bc47d6 100755 --- a/build/rpm/dolibarr_mandriva.spec +++ b/build/rpm/dolibarr_mandriva.spec @@ -189,6 +189,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/loan %_datadir/dolibarr/htdocs/mailmanspip %_datadir/dolibarr/htdocs/margin +%_datadir/dolibarr/htdocs/multicurrency %_datadir/dolibarr/htdocs/opensurvey %_datadir/dolibarr/htdocs/paybox %_datadir/dolibarr/htdocs/paypal @@ -203,6 +204,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/theme %_datadir/dolibarr/htdocs/user %_datadir/dolibarr/htdocs/webservices +%_datadir/dolibarr/htdocs/websites %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec index cc21d7083b3..fcff3363213 100755 --- a/build/rpm/dolibarr_opensuse.spec +++ b/build/rpm/dolibarr_opensuse.spec @@ -200,6 +200,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/loan %_datadir/dolibarr/htdocs/mailmanspip %_datadir/dolibarr/htdocs/margin +%_datadir/dolibarr/htdocs/multicurrency %_datadir/dolibarr/htdocs/opensurvey %_datadir/dolibarr/htdocs/paybox %_datadir/dolibarr/htdocs/paypal @@ -214,6 +215,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/theme %_datadir/dolibarr/htdocs/user %_datadir/dolibarr/htdocs/webservices +%_datadir/dolibarr/htdocs/websites %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/dev/translation/sanity_check_en_langfiles.php b/dev/translation/sanity_check_en_langfiles.php index cd652374489..f64798d72ff 100755 --- a/dev/translation/sanity_check_en_langfiles.php +++ b/dev/translation/sanity_check_en_langfiles.php @@ -316,6 +316,9 @@ if ((! empty($_REQUEST['unused']) && $_REQUEST['unused'] == 'true') || (isset($a if (preg_match('/^EMailText/', $value)) $qualifiedforclean=0; if (preg_match('/ById$/', $value)) $qualifiedforclean=0; if (preg_match('/ByLogin$/', $value)) $qualifiedforclean=0; + // printing + if (preg_match('/PrintingDriverDesc$/', $value)) $qualifiedforclean=0; + if (preg_match('/PrintTestDesc$/', $value)) $qualifiedforclean=0; // products if (preg_match('/GlobalVariableUpdaterType$/', $value)) $qualifiedforclean=0; if (preg_match('/GlobalVariableUpdaterHelp$/', $value)) $qualifiedforclean=0; diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 5ca1197b3e2..2fbf056b0b9 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -166,14 +166,13 @@ if ($action == 'writebookkeeping') { $now = dol_now(); $error = 0; - foreach ( $tabfac as $key => $val ) { - + foreach ($tabfac as $key => $val) + { $companystatic = new Societe($db); $invoicestatic = new FactureFournisseur($db); $invoicestatic->id = $key; - $invoicestatic->ref = $val["ref"]; - $invoicestatic->ref = $val["refsologest"]; + $invoicestatic->ref = (string) $val["refsologest"]; $invoicestatic->refsupplier = $val["refsuppliersologest"]; $invoicestatic->type = $val["type"]; $invoicestatic->description = html_entity_decode(dol_trunc($val["description"], 32)); diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 5da210ca09a..c462f036a9f 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -207,7 +207,7 @@ if ($action == 'writebookkeeping') { $companystatic->client = $tabcompany[$key]['code_client']; $invoicestatic->id = $key; - $invoicestatic->ref = $val["ref"]; + $invoicestatic->ref = (string) $val["ref"]; foreach ( $tabttc[$key] as $k => $mt ) { $bookkeeping = new BookKeeping($db); diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 49048cfaf1f..ac09e1864b6 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -404,11 +404,7 @@ if (empty($reshook)) } else { - if ($object->error) { - setEventMessages($object->error, $object->errors, 'errors'); - } else { - setEventMessages($object->error, $object->errors, 'errors'); - } + setEventMessages($object->error, $object->errors, 'errors'); $action=''; } } @@ -1443,6 +1439,12 @@ else if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) { print ''.$langs->trans("Password").''.preg_replace('/./i','*',$object->pass); + if ($object->pass) print preg_replace('/./i','*',$object->pass); + else + { + if ($user->admin) print $langs->trans("Crypted").': '.$object->pass_indatabase_crypted; + else print $langs->trans("Hidden"); + } if ((! empty($object->pass) || ! empty($object->pass_crypted)) && empty($object->user_id)) { $langs->load("errors"); @@ -1451,7 +1453,7 @@ else } print ''; } - + print ''; print ''; @@ -1483,6 +1485,30 @@ else print $object->showOptionals($extrafields, 'view', $parameters); } + // Date end subscription + print ''.$langs->trans("SubscriptionEndDate").''; + if ($object->datefin) + { + print dol_print_date($object->datefin,'day'); + if ($object->hasDelay()) { + print " ".img_warning($langs->trans("Late")); + } + } + else + { + if (! $adht->cotisation) + { + print $langs->trans("SubscriptionNotRecorded"); + if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated + } + else + { + print $langs->trans("SubscriptionNotReceived"); + if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated + } + } + print ''; + // Third party Dolibarr if (! empty($conf->societe->enabled)) { @@ -1553,30 +1579,6 @@ else } print ''; - // Date end subscription - print ''.$langs->trans("SubscriptionEndDate").''; - if ($object->datefin) - { - print dol_print_date($object->datefin,'day'); - if ($object->hasDelay()) { - print " ".img_warning($langs->trans("Late")); - } - } - else - { - if (! $adht->cotisation) - { - print $langs->trans("SubscriptionNotRecorded"); - if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated - } - else - { - print $langs->trans("SubscriptionNotReceived"); - if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated - } - } - print ''; - print "\n"; print "\n"; diff --git a/htdocs/adherents/card_subscriptions.php b/htdocs/adherents/card_subscriptions.php index dcc8b671259..1299f2400dc 100644 --- a/htdocs/adherents/card_subscriptions.php +++ b/htdocs/adherents/card_subscriptions.php @@ -652,6 +652,30 @@ if ($rowid > 0) print $object->showOptionals($extrafields, 'view', $parameters); } + // Date end subscription + print ''.$langs->trans("SubscriptionEndDate").''; + if ($object->datefin) + { + print dol_print_date($object->datefin,'day'); + if ($object->hasDelay()) { + print " ".img_warning($langs->trans("Late")); + } + } + else + { + if (! $adht->cotisation) + { + print $langs->trans("SubscriptionNotRecorded"); + if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // Affiche picto retard uniquement si non brouillon et non resilie + } + else + { + print $langs->trans("SubscriptionNotReceived"); + if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // Affiche picto retard uniquement si non brouillon et non resilie + } + } + print ''; + // Third party Dolibarr if (! empty($conf->societe->enabled)) { @@ -722,30 +746,6 @@ if ($rowid > 0) } print ''; - // Date end subscription - print ''.$langs->trans("SubscriptionEndDate").''; - if ($object->datefin) - { - print dol_print_date($object->datefin,'day'); - if ($object->hasDelay()) { - print " ".img_warning($langs->trans("Late")); - } - } - else - { - if (! $adht->cotisation) - { - print $langs->trans("SubscriptionNotRecorded"); - if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // Affiche picto retard uniquement si non brouillon et non resilie - } - else - { - print $langs->trans("SubscriptionNotReceived"); - if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // Affiche picto retard uniquement si non brouillon et non resilie - } - } - print ''; - print "\n"; print "\n"; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 87ceb66f9d1..e12c49732dd 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -47,8 +47,15 @@ class Adherent extends CommonObject var $mesgs; var $login; - var $pass; - var $societe; + + //! Clear password in memory + var $pass; + //! Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0) + var $pass_indatabase; + //! Encrypted password in database (always defined) + var $pass_indatabase_crypted; + + var $societe; var $company; var $address; var $zip; @@ -309,7 +316,7 @@ class Adherent extends CommonObject if ($id > 0) { $this->id=$id; - $this->ref=$id; + $this->ref=(string) $id; // Update minor fields $result=$this->update($user,1,1,0,0,'add'); // nosync is 1 to avoid update data of user @@ -482,8 +489,10 @@ class Adherent extends CommonObject dol_syslog(get_class($this)."::update update password"); if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) { - // Si mot de passe saisi et different de celui en base - $result=$this->setPassword($user,$this->pass,0,$notrigger,$nosyncuserpass); + $isencrypted = empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1; + + // If password to set differs from the one found into database + $result=$this->setPassword($user,$this->pass,$isencrypted,$notrigger,$nosyncuserpass); if (! $nbrowsaffected) $nbrowsaffected++; } } @@ -509,7 +518,7 @@ class Adherent extends CommonObject if (! $error && $nbrowsaffected) // If something has change in main data { // Update information on linked user if it is an update - if ($this->user_id > 0 && ! $nosyncuser) + if (! $error && $this->user_id > 0 && ! $nosyncuser) { require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; @@ -552,7 +561,7 @@ class Adherent extends CommonObject } // Update information on linked thirdparty if it is an update - if ($this->fk_soc > 0 && ! $nosyncthirdparty) + if (! $error && $this->fk_soc > 0 && ! $nosyncthirdparty) { require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; @@ -810,13 +819,11 @@ class Adherent extends CommonObject $password=getRandomPassword(false); } - // Cryptage mot de passe - if ($isencrypted) - { - // Encryption - $password_indatabase = dol_hash($password); - } - else + // Crypt password + $password_crypted = dol_hash($password); + + $password_indatabase = ''; + if (! $isencrypted) { $password_indatabase = $password; } @@ -824,7 +831,17 @@ class Adherent extends CommonObject $this->db->begin(); // Mise a jour - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET pass = '".$this->db->escape($password_indatabase)."'"; + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent"; + $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."'"; + //if (! empty($conf->global->DATABASE_PWD_ENCRYPTED)) + if ($isencrypted) + { + $sql.= ", pass = null"; + } + else + { + $sql.= ", pass = '".$this->db->escape($password_indatabase)."'"; + } $sql.= " WHERE rowid = ".$this->id; //dol_syslog("Adherent::Password sql=hidden"); @@ -838,7 +855,8 @@ class Adherent extends CommonObject { $this->pass=$password; $this->pass_indatabase=$password_indatabase; - + $this->pass_indatabase_crypted=$password_crypted; + if ($this->user_id && ! $nosyncuser) { require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; @@ -1042,7 +1060,7 @@ class Adherent extends CommonObject $sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,"; $sql.= " d.note_public,"; - $sql.= " d.email, d.skype, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass,"; + $sql.= " d.email, d.skype, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,"; $sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,"; $sql.= " d.datec as datec,"; $sql.= " d.tms as datem,"; @@ -1087,7 +1105,6 @@ class Adherent extends CommonObject $this->firstname = $obj->firstname; $this->lastname = $obj->lastname; $this->login = $obj->login; - $this->pass = $obj->pass; $this->societe = $obj->company; $this->company = $obj->company; $this->fk_soc = $obj->fk_soc; @@ -1095,6 +1112,10 @@ class Adherent extends CommonObject $this->zip = $obj->zip; $this->town = $obj->town; + $this->pass = $obj->pass; + $this->pass_indatabase = $obj->pass; + $this->pass_indatabase_crypted = $obj->pass_crypted; + $this->state_id = $obj->state_id; $this->state_code = $obj->state_id?$obj->state_code:''; $this->state = $obj->state_id?$obj->state:''; @@ -1423,9 +1444,10 @@ class Adherent extends CommonObject $err=0; // mailman - if (! empty($conf->global->ADHERENT_USE_MAILMAN)) + if (! empty($conf->global->ADHERENT_USE_MAILMAN) && ! empty($conf->mailmanspip->enabled)) { $result=$mailmanspip->add_to_mailman($this); + if ($result < 0) { if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error; @@ -1444,7 +1466,7 @@ class Adherent extends CommonObject } // spip - if ($conf->global->ADHERENT_USE_SPIP && ! empty($conf->mailmanspip->enabled)) + if (! empty($conf->global->ADHERENT_USE_SPIP) && ! empty($conf->mailmanspip->enabled)) { $result=$mailmanspip->add_to_spip($this); if ($result < 0) @@ -1458,7 +1480,7 @@ class Adherent extends CommonObject return -$err; } else - { + { return 1; } } @@ -1556,6 +1578,7 @@ class Adherent extends CommonObject $label.= '
' . $langs->trans('Name') . ': ' . $this->getFullName($langs); $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + $link=''; $linkend=''; if ($option == 'card') { $link = ''; print ''.$langs->trans("CompanyInfo").''.$langs->trans("Value").''."\n"; + // Name $var=!$var; print ''; print ''."\n"; + // Addresse $var=!$var; print ''; print ''."\n"; @@ -392,7 +394,7 @@ if ($action == 'edit' || $action == 'updateedit') // Note $var=!$var; print ''; - print ''; + print ''; print ''; print ''; @@ -531,7 +533,7 @@ if ($action == 'edit' || $action == 'updateedit') // Object of the company $var=!$var; print ''; - print ''; + print ''; print ''; print ''; diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index 9209542a9c0..b299a1f18fe 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -62,6 +62,23 @@ if ($action == 'update') { if (! $_POST['cancel']) { + $leftmenu=''; $mainmenu=''; + if (! empty($_POST['menuIdParent']) && ! is_numeric($_POST['menuIdParent'])) + { + $tmp=explode('&',$_POST['menuIdParent']); + foreach($tmp as $s) + { + if (preg_match('/fk_mainmenu=/',$s)) + { + $mainmenu=preg_replace('/fk_mainmenu=/','',$s); + } + if (preg_match('/fk_leftmenu=/',$s)) + { + $leftmenu=preg_replace('/fk_leftmenu=/','',$s); + } + } + } + $menu = new Menubase($db); $result=$menu->fetch($_POST['menuId']); if ($result > 0) @@ -75,7 +92,18 @@ if ($action == 'update') $menu->perms=$_POST['perms']; $menu->target=$_POST['target']; $menu->user=$_POST['user']; - $menu->fk_menu=$_POST['fk_menu']; + if (is_numeric($_POST['menuIdParent'])) + { + $menu->fk_menu=$_POST['menuIdParent']; + } + else + { + if ($_POST['type'] == 'top') $menu->fk_menu=0; + else $menu->fk_menu=-1; + $menu->fk_mainmenu=$mainmenu; + $menu->fk_leftmenu=$leftmenu; + } + $result=$menu->update($user); if ($result > 0) { @@ -342,7 +370,7 @@ if ($action == 'create') } else { - print ''; + print ''; } print ''.$langs->trans('DetailMenuIdParent'); print ', '.$langs->trans("Example").': fk_mainmenu=abc&fk_leftmenu=def'; @@ -425,12 +453,15 @@ elseif ($action == 'edit') print ''.$langs->trans('Type').''.$langs->trans(ucfirst($menu->type)).''.$langs->trans('DetailType').''; // MenuId Parent - print ''.$langs->trans('MenuIdParent').''; + print ''.$langs->trans('MenuIdParent'); + print ''; $valtouse=$menu->fk_menu; if ($menu->fk_mainmenu) $valtouse='fk_mainmenu='.$menu->fk_mainmenu; if ($menu->fk_leftmenu) $valtouse.='&fk_leftmenu='.$menu->fk_leftmenu; - print ''; - print ''.$langs->trans('DetailMenuIdParent').''; + print ''; + print ''.$langs->trans('DetailMenuIdParent'); + print ', '.$langs->trans("Example").': fk_mainmenu=abc&fk_leftmenu=def'; + print ''; // Niveau //print ''.$langs->trans('Level').''.$menu->level.''.$langs->trans('DetailLevel').''; diff --git a/htdocs/admin/menus/index.php b/htdocs/admin/menus/index.php index cba8d45c8f3..c8b7b469bd2 100644 --- a/htdocs/admin/menus/index.php +++ b/htdocs/admin/menus/index.php @@ -361,7 +361,7 @@ if ($conf->use_javascript_ajax) if (count($remainingdata)) { - print ''; + print '
'; print ''; print ''; diff --git a/htdocs/admin/tools/export.php b/htdocs/admin/tools/export.php index 175aaa65665..5ace954045a 100644 --- a/htdocs/admin/tools/export.php +++ b/htdocs/admin/tools/export.php @@ -53,6 +53,8 @@ if ($file && ! $what) exit; } +$errormsg=''; + /* * Actions @@ -120,16 +122,37 @@ if ($what == 'mysql') { $cmddump=GETPOST("mysqldump"); // Do not sanitize here with 'alpha', will be sanitize later by escapeshellarg - if ($cmddump) + if (! empty($dolibarr_main_restrict_os_commands)) + { + $arrayofallowedcommand=explode(',', $dolibarr_main_restrict_os_commands); + $ok=0; + dol_syslog("Command are restricted to ".$dolibarr_main_restrict_os_commands.". We check that on of this command is inside ".$cmddump); + foreach($arrayofallowedcommand as $allowedcommand) + { + if (preg_match('/'.preg_quote($allowedcommand,'/').'/', $cmddump)) + { + $ok=1; + break; + } + } + if (! $ok) + { + $errormsg=$langs->trans('CommandIsNotInsideAllowedCommands'); + } + } + + if (! $errormsg && $cmddump) { dolibarr_set_const($db, 'SYSTEMTOOLS_MYSQLDUMP', $cmddump,'chaine',0,'',$conf->entity); } - $utils->dumpDatabase(GETPOST('compression','alpha'), $what, 0, $file); - - $errormsg=$utils->error; - $_SESSION["commandbackuplastdone"]=$utils->result['commandbackuplastdone']; - $_SESSION["commandbackuptorun"]=$utils->result['commandbackuptorun']; + if (! $errormsg) + { + $utils->dumpDatabase(GETPOST('compression','alpha'), $what, 0, $file); + $errormsg=$utils->error; + $_SESSION["commandbackuplastdone"]=$utils->result['commandbackuplastdone']; + $_SESSION["commandbackuptorun"]=$utils->result['commandbackuptorun']; + } } // MYSQL NO BIN @@ -146,16 +169,19 @@ if ($what == 'mysqlnobin') if ($what == 'postgresql') { $cmddump=GETPOST("postgresqldump"); // Do not sanitize here with 'alpha', will be sanitize later by escapeshellarg - if ($cmddump) + + if (! $errormsg && $cmddump) { dolibarr_set_const($db, 'SYSTEMTOOLS_POSTGRESQLDUMP', $cmddump,'chaine',0,'',$conf->entity); } - $utils->dumpDatabase(GETPOST('compression','alpha'), $what, 0, $file); - - $errormsg=$utils->error; - $_SESSION["commandbackuplastdone"]=$utils->result['commandbackuplastdone']; - $_SESSION["commandbackuptorun"]=$utils->result['commandbackuptorun']; + if (! $errormsg) + { + $utils->dumpDatabase(GETPOST('compression','alpha'), $what, 0, $file); + $errormsg=$utils->error; + $_SESSION["commandbackuplastdone"]=$utils->result['commandbackuplastdone']; + $_SESSION["commandbackuptorun"]=$utils->result['commandbackuptorun']; + } $what=''; // Clear to show message to run command } diff --git a/htdocs/cashdesk/include/environnement.php b/htdocs/cashdesk/include/environnement.php index 3e6a88f252a..4490d4cf405 100644 --- a/htdocs/cashdesk/include/environnement.php +++ b/htdocs/cashdesk/include/environnement.php @@ -44,7 +44,7 @@ $conf_fkaccount_cb = (! empty($_SESSION["CASHDESK_ID_BANKACCOUNT_CB"]))?$_SESSIO // View parameters -$conf_taille_listes = (empty($conf->global->PRODUIT_LIMIT_SIZE)?500:$conf->global->PRODUIT_LIMIT_SIZE); // Nombre max de lignes a afficher dans les listes +$conf_taille_listes = (empty($conf->global->PRODUIT_LIMIT_SIZE)?1000:$conf->global->PRODUIT_LIMIT_SIZE); // Nombre max de lignes a afficher dans les listes $conf_nbr_car_listes = 60; // Nombre max de caracteres par ligne dans les listes // Add hidden option to force decrease of stock whatever is user setup diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php index 1775c14767d..c347b4863c7 100644 --- a/htdocs/categories/categorie.php +++ b/htdocs/categories/categorie.php @@ -617,13 +617,14 @@ else if ($id || $ref) * @param Object $object Object we want to see categories it can be classified into * @param int $typeid Type of category (0, 1, 2, 3) * @param int $socid Id thirdparty - * @param int $showclassifyform 1=Add form to 'Classify', 0=Do not show form to 'Classify' + * @param int $showclassifyform 1=Add form to 'Classify', 0=Do not show form to 'Classify' * @return int 0 */ function formCategory($db,$object,$typeid,$socid=0,$showclassifyform=1) { global $user,$langs,$form,$bc; + $title='NotDefined'; if ($typeid == Categorie::TYPE_PRODUCT) $title = $langs->trans("ProductsCategoriesShort"); if ($typeid == Categorie::TYPE_SUPPLIER) $title = $langs->trans("SuppliersCategoriesShort"); if ($typeid == Categorie::TYPE_CUSTOMER) $title = $langs->trans("CustomersProspectsCategoriesShort"); diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 7c7c35d4b05..8636232b405 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -43,13 +43,13 @@ require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; class Categorie extends CommonObject { // Categories types - const TYPE_PRODUCT = 0; - const TYPE_SUPPLIER = 1; - const TYPE_CUSTOMER = 2; - const TYPE_MEMBER = 3; - const TYPE_CONTACT = 4; - const TYPE_USER = 4; // categorie contact and user are same ! - const TYPE_ACCOUNT = 5; // bank account + const TYPE_PRODUCT = 0; // TODO Replace with value 'product' + const TYPE_SUPPLIER = 1; // TODO Replace this value with 'supplier' + const TYPE_CUSTOMER = 2; // TODO Replace this value with 'customer' + const TYPE_MEMBER = 3; // TODO Replace this value with 'member' + const TYPE_CONTACT = 4; // TODO Replace this value with 'contact' + const TYPE_USER = 4; // categorie contact and user are same ! TODO Replace this value with 'user' + const TYPE_ACCOUNT = 5; // for bank account TODO Replace this value with 'account' /** * @var array ID mapping from type string @@ -63,7 +63,7 @@ class Categorie extends CommonObject 'member' => 3, 'contact' => 4, 'user' => 4, - 'account' => 5, + 'account' => 5, ); /** * @var array Foreign keys mapping from type string diff --git a/htdocs/comm/action/class/ical.class.php b/htdocs/comm/action/class/ical.class.php index 54f97fa2117..8254a5de1ba 100644 --- a/htdocs/comm/action/class/ical.class.php +++ b/htdocs/comm/action/class/ical.class.php @@ -208,7 +208,7 @@ class ICal //print 'type='.$type.' key='.$key.' value='.$value.'
'."\n"; - if ($key == false) + if (empty($key)) { $key = $this->last_key; switch ($type) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 43416875d95..ffc412fba70 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2611,7 +2611,8 @@ class Propal extends CommonObject { global $langs; - // Charge tableau des produits prodids + // Load array of products prodids + $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 8fcc7d41ef1..6f14d407a5d 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -449,6 +449,8 @@ class Commande extends CommonOrder // If stock is decremented on validate order, we must reincrement it if (! empty($conf->stock->enabled) && $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER == 1) { + $result = 0; + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; $langs->load("agenda"); @@ -460,22 +462,9 @@ class Commande extends CommonOrder $mouvP = new MouvementStock($this->db); // We increment stock of product (and sub-products) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("OrderBackToDraftInDolibarr",$this->ref)); - if ($result < 0) { $error++; } + if ($result < 0) { $error++; $this->error=$mouvP->error; break; } } } - - if (!$error) - { - $this->statut=self::STATUS_DRAFT; - $this->db->commit(); - return $result; - } - else - { - $this->error=$mouvP->error; - $this->db->rollback(); - return $result; - } } if (!$error) { @@ -3258,7 +3247,8 @@ class Commande extends CommonOrder dol_syslog(get_class($this)."::initAsSpecimen"); - // Charge tableau des produits prodids + // Load array of products prodids + $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; diff --git a/htdocs/commande/orderstoinvoice.php b/htdocs/commande/orderstoinvoice.php index bcbe3ea408e..64c52764599 100644 --- a/htdocs/commande/orderstoinvoice.php +++ b/htdocs/commande/orderstoinvoice.php @@ -72,7 +72,7 @@ $date_endy = dol_mktime(23,59,59,$_REQUEST["date_end_delymonth"],$_REQUEST["date if ($action == 'create') { - if (is_array($selected) == false) + if (! is_array($selected)) { $error++; setEventMessages($langs->trans('Error_OrderNotChecked'), null, 'errors'); diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index e6043167b22..5ba06842c30 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -89,8 +89,7 @@ if ($_POST["action"] == 'add') $account->proprio = trim($_POST["proprio"]); $account->owner_address = trim($_POST["owner_address"]); - if (GETPOST('account_number') <= 0) { $accountancy_code_number = ''; } else { $accountancy_code_number = GETPOST('account_number'); } - $account->account_number = $accountancy_code_number; + $account->account_number = GETPOST('account_number'); $account->accountancy_journal = trim($_POST["accountancy_journal"]); $account->solde = $_POST["solde"]; @@ -172,8 +171,7 @@ if ($_POST["action"] == 'update' && ! $_POST["cancel"]) $account->proprio = trim($_POST["proprio"]); $account->owner_address = trim($_POST["owner_address"]); - if (GETPOST('account_number') <= 0) { $accountancy_code_number = ''; } else { $accountancy_code_number = GETPOST('account_number'); } - $account->account_number = $accountancy_code_number; + $account->account_number = GETPOST('account_number'); $account->accountancy_journal = trim($_POST["accountancy_journal"]); $account->currency_code = trim($_POST["account_currency_code"]); @@ -287,7 +285,7 @@ if ($action == 'create') // Ref print ''; - print ''; + print ''; // Label print ''; @@ -393,10 +391,10 @@ if ($action == 'create') print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print '
'.$langs->trans("NotTopTreeMenuPersonalized").'
'.$langs->trans("Ref").'ref).'" maxlength="12">
ref).'" maxlength="12">
'.$langs->trans("LabelBankCashAccount").'
'.$langs->trans("BalanceMinimalAllowed").'min_allowed).'">
min_allowed).'">
'.$langs->trans("BalanceMinimalDesired").'min_desired).'">
min_desired).'">
'; print '
'; @@ -407,7 +405,7 @@ if ($action == 'create') // If bank account print ''.$langs->trans("BankName").''; - print ''; + print ''; print ''; // Show fields of bank account @@ -431,7 +429,7 @@ if ($action == 'create') } print ''.$langs->trans($val).''; - print ''; + print ''; print ''; } $ibankey = FormBank::getIBANLabel($account); @@ -440,23 +438,23 @@ if ($action == 'create') // IBAN print ''.$langs->trans($ibankey).''; - print ''; + print ''; print ''.$langs->trans($bickey).''; - print ''; + print ''; print ''.$langs->trans("BankAccountDomiciliation").''; print ""; print ''.$langs->trans("BankAccountOwner").''; - print ''; + print ''; print ''; print ''.$langs->trans("BankAccountOwnerAddress").''; print ""; print ''; diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 34cec22fb54..a5038fc2e78 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -45,16 +45,9 @@ $statut=GETPOST('statut'); * View */ -$help_url='EN:Module_Banks_and_Cash|FR:Module_Banques_et_Caisses|ES:Módulo_Bancos_y_Cajas'; -llxHeader('',$langs->trans('AccountsArea'),$help_url); +$title=$langs->trans('BankAccounts'); -$link=''; -if ($statut == '') $link='
'.$langs->trans("IncludeClosedAccount").''; -if ($statut == 'all') $link=''.$langs->trans("OnlyOpenedAccount").''; -print load_fiche_titre($langs->trans("AccountsArea"),$link, 'title_bank.png'); - - -// On charge tableau des comptes financiers (ouverts par defaut) +// Load array of financial accounts (opened by default) $accounts = array(); $sql = "SELECT rowid, courant, rappro"; @@ -66,17 +59,30 @@ $sql.= $db->order('label', 'ASC'); $resql = $db->query($sql); if ($resql) { - $num = $db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $objp = $db->fetch_object($resql); - $accounts[$objp->rowid] = $objp->courant; - $i++; - } - $db->free($resql); + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $objp = $db->fetch_object($resql); + $accounts[$objp->rowid] = $objp->courant; + $i++; + } + $db->free($resql); } +$nbtotalofrecords = $num; + + +$help_url='EN:Module_Banks_and_Cash|FR:Module_Banques_et_Caisses|ES:Módulo_Bancos_y_Cajas'; +llxHeader('',$title,$help_url); + +$link=''; +if ($statut == '') $link=''.$langs->trans("IncludeClosedAccount").''; +if ($statut == 'all') $link=''.$langs->trans("OnlyOpenedAccount").''; + +print_barre_liste($title,$page,$_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,$link,$num,$nbtotalofrecords,'title_bank.png',0,'','',$limit, 1); + + /* * Comptes courants (courant = 1) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 2bcd227827e..1d75be61f6c 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -509,7 +509,7 @@ class FactureRec extends CommonInvoice $facid=$this->id; - dol_syslog("FactureRec::addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,fk_product=$fk_product,remise_percent=$remise_percent,date_start=$date_start,date_end=$date_end,ventil=$ventil,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit", LOG_DEBUG); + dol_syslog(get_class($this)."::addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,fk_product=$fk_product,remise_percent=$remise_percent,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; // Check parameters @@ -604,6 +604,111 @@ class FactureRec extends CommonInvoice } } + /** + * Update a line to invoice + * + * @param int $rowid Id of line to update + * @param string $desc Description de la ligne + * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) + * @param double $qty Quantite + * @param double $txtva Taux de tva force, sinon -1 + * @param int $fk_product Id du produit/service predefini + * @param double $remise_percent Pourcentage de remise de la ligne + * @param string $price_base_type HT or TTC + * @param int $info_bits Bits de type de lignes + * @param int $fk_remise_except Id remise + * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) + * @param int $type Type of line (0=product, 1=service) + * @param int $rang Position of line + * @param int $special_code Special code + * @param string $label Label of the line + * @param string $fk_unit Unit + * @return int <0 if KO, Id of line if OK + */ + function updateline($rowid, $desc, $pu_ht, $qty, $txtva, $fk_product=0, $remise_percent=0, $price_base_type='HT', $info_bits=0, $fk_remise_except='', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $label='', $fk_unit=null) + { + global $mysoc; + + $facid=$this->id; + + dol_syslog(get_class($this)."::updateline facid=".$facid." rowid=$rowid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,fk_product=$fk_product,remise_percent=$remise_percent,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit", LOG_DEBUG); + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + // Check parameters + if ($type < 0) return -1; + + if ($this->brouillon) + { + // Clean parameters + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + if (! $qty) $qty=1; + if (! $info_bits) $info_bits=0; + $pu_ht=price2num($pu_ht); + $pu_ttc=price2num($pu_ttc); + $txtva=price2num($txtva); + + if ($price_base_type=='HT') + { + $pu=$pu_ht; + } + else + { + $pu=$pu_ttc; + } + + // Calcul du total TTC et de la TVA pour la ligne a partir de + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, 0, 0, 0, $price_base_type, $info_bits, $type, $mysoc); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + + $product_type=$type; + if ($fk_product) + { + $product=new Product($this->db); + $result=$product->fetch($fk_product); + $product_type=$product->type; + } + + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET "; + $sql.= "fk_facture = '".$facid."'"; + $sql.= ", label=".(! empty($label)?"'".$this->db->escape($label)."'":"null"); + $sql.= ", description='".$this->db->escape($desc)."'"; + $sql.= ", price=".price2num($pu_ht); + $sql.= ", qty=".price2num($qty); + $sql.= ", tva_tx=".price2num($txtva); + $sql.= ", fk_product=".(! empty($fk_product)?"'".$fk_product."'":"null"); + $sql.= ", product_type=".$product_type; + $sql.= ", remise_percent='".price2num($remise_percent)."'"; + $sql.= ", subprice='".price2num($pu_ht)."'"; + $sql.= ", total_ht='".price2num($total_ht)."'"; + $sql.= ", total_tva='".price2num($total_tva)."'"; + $sql.= ", total_ttc='".price2num($total_ttc)."'"; + $sql.= ", rang=".$rang; + $sql.= ", special_code=".$special_code; + $sql.= ", fk_unit=".($fk_unit?"'".$this->db->escape($fk_unit)."'":"null"); + $sql.= " WHERE rowid = ".$rowid; + + dol_syslog(get_class($this)."::updateline", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->id=$facid; + $this->update_price(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + } + + /** * Return the next date of * @@ -760,8 +865,9 @@ class FactureRec extends CommonInvoice $arraynow=dol_getdate($now); $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); - $prodids = array(); + // Load array of products prodids $num_prods = 0; + $prodids = array(); $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 95d24d2ce06..aa51c63374d 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3537,6 +3537,8 @@ class Facture extends CommonInvoice $arraynow=dol_getdate($now); $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); + // Load array of products prodids + $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 7b2d7076aca..198b08cb451 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -552,9 +552,9 @@ if ($action == 'addline' && $user->rights->facture->creer) if ($result > 0) { - // Define output language /*if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language $outputlangs = $langs; $newlang = ''; if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); @@ -615,8 +615,168 @@ if ($action == 'addline' && $user->rights->facture->creer) } } +elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel')) +{ + if (! $object->fetch($id) > 0) dol_print_error($db); + $object->fetch_thirdparty(); + + // Clean parameters + $date_start = ''; + $date_end = ''; + //$date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + //$date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc') ? GETPOST('product_desc') : GETPOST('desc')); + $pu_ht = GETPOST('price_ht'); + $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + $qty = GETPOST('qty'); + + // Define info_bits + $info_bits = 0; + if (preg_match('/\*/', $vat_rate)) + $info_bits |= 0x01; + + // Define vat_rate + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty); + $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); + + // Add buying price + $fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : ''); + $buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we muste keep this value + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + // Define special_code for special lines + $special_code=GETPOST('special_code'); + if (! GETPOST('qty')) $special_code=3; + + /*$line = new FactureLigne($db); + $line->fetch(GETPOST('lineid')); + $percent = $line->get_prev_progress($object->id); + + if (GETPOST('progress') < $percent) + { + $mesg = '
' . $langs->trans("CantBeLessThanMinPercent") . '
'; + setEventMessages($mesg, null, 'warnings'); + $error++; + $result = -1; + }*/ + + // Check minimum price + $productid = GETPOST('productid', 'int'); + if (! empty($productid)) + { + $product = new Product($db); + $product->fetch($productid); + + $type = $product->type; + + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level)) + $price_min = $product->multiprices_min [$object->thirdparty->price_level]; + + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); + + // Check price is not lower than minimum (check is done only for standard or replacement invoices) + if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { + setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors'); + $error ++; + } + } else { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + + // Check parameters + if (GETPOST('type') < 0) { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors'); + $error ++; + } + } + if ($qty < 0) { + $langs->load("errors"); + setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors'); + $error ++; + } + + // Update line + if (! $error) { + $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $qty, + $vat_rate, GETPOST('productid'), GETPOST('remise_percent'), 'HT', $info_bits, 0, 0, $type, + 0, $special_code, $label, GETPOST('units')); + + if ($result >= 0) { + /*if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + }*/ + + $object->fetch($object->id); // Reload lines + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['productid']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['multicurrency_price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + unset($_POST['np_marginRate']); + unset($_POST['np_markRate']); + + unset($_POST['dp_desc']); + unset($_POST['idprod']); + unset($_POST['units']); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); + + unset($_POST['situations']); + unset($_POST['progress']); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } +} + // Do we click on purge search criteria ? -if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // All test are required to be compatible with all browsers { $search_ref=''; $search_societe=''; @@ -1302,7 +1462,7 @@ else // Show object lines if (! empty($object->lines)) { - $disableedit=1; + //$disableedit=1; //$disablemove=1; $ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 0); // No date selector for template invoice } diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example index 3d6db94d801..6ca98728312 100644 --- a/htdocs/conf/conf.php.example +++ b/htdocs/conf/conf.php.example @@ -220,6 +220,25 @@ $dolibarr_main_authentication='dolibarr'; // $dolibarr_main_force_https='0'; +// dolibarr_main_prod +// When this parameter is defined, all errors messages are not reported. +// This feature exists for production usage to avoid to give any information to hackers. +// Default value: 0 +// Possible values: 0 or 1 +// Examples: +// $dolibarr_main_prod='0'; +// +$dolibarr_main_prod='0'; + +// $dolibarr_main_restrict_os_commands +// To restrict commands you can execute by the backup feature, enter allowed command here. +// Note: If you can, defining permission on OS linux (using SELinux for example) may be a better choice. +// Default value: 'mysqldump, mysql, pg_dump, pgrestore' +// Examples: +// $dolibarr_main_restrict_os_commands='mysqldump, /usr/local/bin/otherdumptool'; +// +$dolibarr_main_restrict_os_commands='mysqldump, mysql, pg_dump, pgrestore'; + // dolibarr_nocsrfcheck // This parameter can be used to disable CSRF protection. // This might be required if you access Dolibarr behind a proxy that make @@ -231,15 +250,11 @@ $dolibarr_main_force_https='0'; // $dolibarr_nocsrfcheck='0'; -// dolibarr_main_prod -// When this parameter is defined, all errors messages are not reported. -// This feature exists for production usage to avoid to give any information to hackers. -// Default value: 0 -// Possible values: 0 or 1 +// dolibarr_mailing_limit_sendbyweb +// Can set a limit for mailing send by web. Can be used for a restricted mode. +// Default value: 0 (use database value if exist) // Examples: -// $dolibarr_main_prod='0'; -// -$dolibarr_main_prod='0'; +// $dolibarr_mailing_limit_sendbyweb='0'; @@ -251,8 +266,6 @@ $dolibarr_main_prod='0'; // This parameter contains prefix of Dolibarr database. 'llx_' if not defined. // Examples: // $dolibarr_main_db_prefix='llx_'; -// -$dolibarr_main_db_prefix=''; // dolibarr_main_limit_users // Can set a limit on the number of users it will be possible to create @@ -261,12 +274,6 @@ $dolibarr_main_db_prefix=''; // Examples: // $dolibarr_main_limit_users='0'; -// dolibarr_mailing_limit_sendbyweb -// Can set a limit for mailing send by web. Can be used for a restricted mode. -// Default value: 0 (use database value if exist) -// Examples: -// $dolibarr_mailing_limit_sendbyweb='0'; - // dolibarr_strict_mode // Set this to 1 to enable the PHP strict mode. For dev environment only. // Default value: 0 (use database value if exist) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 47cde8e3f40..fd92db95dfc 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2098,6 +2098,8 @@ class Contrat extends CommonObject { global $user,$langs,$conf; + // Load array of products prodids + $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; @@ -2116,8 +2118,6 @@ class Contrat extends CommonObject } } - - // Initialise parametres $this->id=0; $this->specimen=1; diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php index 5f04e42cc9b..061b98d1e9c 100644 --- a/htdocs/core/actions_printing.inc.php +++ b/htdocs/core/actions_printing.inc.php @@ -1,6 +1,6 @@ - * Copyright (C) 2014 Frederic France +/* Copyright (C) 2014-2016 Laurent Destailleur + * Copyright (C) 2014 Frederic France * * 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 @@ -44,7 +44,8 @@ if ($action == 'print_file' and $user->rights->printing->read) $printer = new $classname($db); //print '
'.print_r($printer, true).'
'; - if (! empty($conf->global->{$printer->active})) { + if (! empty($conf->global->{$printer->active})) + { $subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':''); $module = GETPOST('printer', 'alpha'); if ($module =='commande_fournisseur') { @@ -56,10 +57,11 @@ if ($action == 'print_file' and $user->rights->printing->read) //print '
'.print_r($printer->errors, true).'
'; setEventMessages($printer->error, $printer->errors, 'errors'); } - if ($ret==0) { + if ($ret==0) + { //print '
'.print_r($printer->errors, true).'
'; setEventMessages($printer->error, $printer->errors); - setEventMessages($langs->trans("FileWasSentToPrinter", basename(GETPOST('file'))).' '.$langs->trans("ViaModule").' '.$printer->name, null); + setEventMessages($langs->trans("FileWasSentToPrinter", basename(GETPOST('file'))).' '.$langs->transnoentitiesnoconv("ViaModule").' '.$printer->name, null); $printed++; } } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 83499a85b3a..620047014d4 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3998,14 +3998,13 @@ abstract class CommonObject { if (!empty($this->errors)) { - $this->errors=array_merge($this->errors,$interface->errors); + $this->errors=array_unique(array_merge($this->errors,$interface->errors)); // We use array_unique because when a trigger call another trigger on same object, this->errors is added twice. } else { $this->errors=$interface->errors; } } - return $result; } diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 35b0d4024ec..4002f437ede 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -429,7 +429,7 @@ class Conf $this->liste_limit=$this->global->MAIN_SIZE_LISTE_LIMIT; // conf->product->limit_size = constante de taille maximale des select de produit - if (! isset($this->global->PRODUIT_LIMIT_SIZE)) $this->global->PRODUIT_LIMIT_SIZE=100; + if (! isset($this->global->PRODUIT_LIMIT_SIZE)) $this->global->PRODUIT_LIMIT_SIZE=1000; $this->product->limit_size=$this->global->PRODUIT_LIMIT_SIZE; // conf->theme et $this->css diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 283d189377c..32f0790fd89 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -633,7 +633,8 @@ class ExtraFields } else { - print dol_print_error($this->db); + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this)."::fetch_name_optionals_label ".$this->error, LOG_ERR); } return $array_name_label; diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php index 1ac219029fd..029aaef1116 100644 --- a/htdocs/core/class/interfaces.class.php +++ b/htdocs/core/class/interfaces.class.php @@ -191,10 +191,12 @@ class Interfaces if ($result < 0) { // Action KO + //dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($objMod->errors), LOG_ERR); $nbtotal++; $nbko++; if (! empty($objMod->errors)) $this->errors=array_merge($this->errors,$objMod->errors); else if (! empty($objMod->error)) $this->errors[]=$objMod->error; + //dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($this->errors), LOG_ERR); } } else @@ -205,7 +207,7 @@ class Interfaces if ($nbko) { - dol_syslog(get_class($this)."::run_triggers action=".$action." Files found: ".$nbfile.", Files launched: ".$nbtotal.", Done: ".$nbok.", Failed: ".$nbko, LOG_ERR); + dol_syslog(get_class($this)."::run_triggers action=".$action." Files found: ".$nbfile.", Files launched: ".$nbtotal.", Done: ".$nbok.", Failed: ".$nbko." - Nb of error string returned in this->errors = ".count($this->errors), LOG_ERR); return -$nbko; } else diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index c0757de2d6b..06bd6dc0c40 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -167,7 +167,7 @@ class Translate if (empty($domain)) { dol_print_error('',get_class($this)."::Load ErrorWrongParameters"); - exit; + return -1; } if ($this->defaultlang == 'none_NONE') return 0; // Special language code to not translate keys diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index 4e14c6987c0..5a9a446596f 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -163,10 +163,13 @@ class DoliDBPgsql extends DoliDB } if ($line != "") { - // group_concat support (PgSQL >= 9.1) - $line = preg_replace('/GROUP_CONCAT/i', 'STRING_AGG', $line); + // group_concat support (PgSQL >= 9.0) + // Replace group_concat(x) or group_concat(x SEPARATOR ',') with string_agg(x, ',') + $line = preg_replace('/GROUP_CONCAT/i', 'STRING_AGG', $line); $line = preg_replace('/ SEPARATOR/i', ',', $line); - + $line = preg_replace('/STRING_AGG\(([^,\)]+)\)/i', 'STRING_AGG(\\1, \',\')', $line); + //print $line."\n"; + if ($type == 'auto') { if (preg_match('/ALTER TABLE/i',$line)) $type='dml'; @@ -315,10 +318,6 @@ class DoliDBPgsql extends DoliDB } } - // Replace group_concat(x) with string_agg(x, ',') - $line=preg_replace('/GROUP_CONCAT\(([^\)]+)\)/i','STRING_AGG(\\1, \',\')',$line); - //print $line."\n"; - // Remove () in the tables in FROM if 1 table $line=preg_replace('/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i','FROM \\1',$line); //print $line."\n"; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 495d7ce1c3c..136e31bd23a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4548,9 +4548,9 @@ function dol_textishtml($msg,$option=0) if (preg_match('//i',$msg)) return true; - elseif (preg_match('/<(br|div|font|li|span|strong|table)>/i',$msg)) return true; - elseif (preg_match('/<(br|div|font|li|span|strong|table)\s+[^<>\/]*>/i',$msg)) return true; - elseif (preg_match('/<(br|div|font|li|span|strong|table)\s+[^<>\/]*\/>/i',$msg)) return true; + elseif (preg_match('/<(br|div|font|li|p|span|strong|table)>/i',$msg)) return true; + elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*>/i',$msg)) return true; + elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*\/>/i',$msg)) return true; elseif (preg_match('/]*src[^<>]*>/i',$msg)) return true; // must accept elseif (preg_match('/]*href[^<>]*>/i',$msg)) return true; // must accept elseif (preg_match('//i',$msg)) return true; diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 05b3bbf054d..17079bc96ac 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -78,11 +78,19 @@ function print_auguria_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$m if (! preg_match("/^(http:\/\/|https:\/\/)/i",$newTabMenu[$i]['url'])) { - $tmp=explode('?',$newTabMenu[$i]['url'],2); + $tmp=explode('?',$newTabMenu[$i]['url'],2); $url = $shorturl = $tmp[0]; $param = (isset($tmp[1])?$tmp[1]:''); - if (! preg_match('/mainmenu/i',$param) || ! preg_match('/leftmenu/i',$param)) $param.=($param?'&':'').'mainmenu='.$newTabMenu[$i]['mainmenu'].'&leftmenu='; + // Complete param to force leftmenu to '' to closed opend menu when we click on a link with no leftmenu defined. + if ((! preg_match('/mainmenu/i',$param)) && (! preg_match('/leftmenu/i',$param)) && ! empty($newTabMenu[$i]['url'])) + { + $param.=($param?'&':'').'mainmenu='.$newTabMenu[$i]['url'].'&leftmenu='; + } + if ((! preg_match('/mainmenu/i',$param)) && (! preg_match('/leftmenu/i',$param)) && empty($newTabMenu[$i]['url'])) + { + $param.=($param?'&':'').'leftmenu='; + } //$url.="idmenu=".$newTabMenu[$i]['rowid']; // Already done by menuLoad $url = dol_buildpath($url,1).($param?'?'.$param:''); $shorturl = $shorturl.($param?'?'.$param:''); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 3e02aa67131..8b6e43d0de8 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -857,8 +857,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu { $langs->load("donations"); $newmenu->add("/don/index.php?leftmenu=donations&mainmenu=accountancy",$langs->trans("Donations"), 0, $user->rights->don->lire, '', $mainmenu, 'donations'); - if (empty($leftmenu) || $leftmenu=="donations") $newmenu->add("/don/card.php?action=create",$langs->trans("NewDonation"), 1, $user->rights->don->creer); - if (empty($leftmenu) || $leftmenu=="donations") $newmenu->add("/don/list.php",$langs->trans("List"), 1, $user->rights->don->lire); + if (empty($leftmenu) || $leftmenu=="donations") $newmenu->add("/don/card.php?leftmenu=donations&action=create",$langs->trans("NewDonation"), 1, $user->rights->don->creer); + if (empty($leftmenu) || $leftmenu=="donations") $newmenu->add("/don/list.php?leftmenu=donations",$langs->trans("List"), 1, $user->rights->don->lire); // if ($leftmenu=="donations") $newmenu->add("/don/stats/index.php",$langs->trans("Statistics"), 1, $user->rights->don->lire); } @@ -1058,6 +1058,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/compta/bank/index.php?leftmenu=bank&mainmenu=bank",$langs->trans("MenuBankCash"),0,$user->rights->banque->lire, '', $mainmenu, 'bank'); $newmenu->add("/compta/bank/card.php?action=create",$langs->trans("MenuNewFinancialAccount"),1,$user->rights->banque->configurer); + $newmenu->add("/compta/bank/index.php?leftmenu=bank&mainmenu=bank",$langs->trans("List"),1,$user->rights->banque->lire, '', $mainmenu, 'bank'); $newmenu->add("/compta/bank/search.php",$langs->trans("ListTransactions"),1,$user->rights->banque->lire); $newmenu->add("/compta/bank/budget.php",$langs->trans("ListTransactionsByCategory"),1,$user->rights->banque->lire); @@ -1184,9 +1185,9 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $langs->load("projects"); // Project affected to user - $newmenu->add("/projet/index.php?leftmenu=projects&mode=mine", $langs->trans("MyProjects"), 0, $user->rights->projet->lire, '', $mainmenu, 'myprojects'); - $newmenu->add("/projet/card.php?leftmenu=projects&action=create&mode=mine", $langs->trans("NewProject"), 1, $user->rights->projet->creer); - $newmenu->add("/projet/list.php?leftmenu=projects&mode=mine&search_status=1", $langs->trans("List"), 1, $user->rights->projet->lire); + $newmenu->add("/projet/index.php?leftmenu=myprojects&mode=mine", $langs->trans("MyProjects"), 0, $user->rights->projet->lire, '', $mainmenu, 'myprojects'); + $newmenu->add("/projet/card.php?leftmenu=myprojects&action=create&mode=mine", $langs->trans("NewProject"), 1, $user->rights->projet->creer); + $newmenu->add("/projet/list.php?leftmenu=myprojects&mode=mine&search_status=1", $langs->trans("List"), 1, $user->rights->projet->lire); // All project i have permission on $newmenu->add("/projet/index.php?leftmenu=projects", $langs->trans("Projects"), 0, $user->rights->projet->lire && $user->rights->projet->lire, '', $mainmenu, 'projects'); @@ -1197,10 +1198,10 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (empty($conf->global->PROJECT_HIDE_TASKS)) { // Project affected to user - $newmenu->add("/projet/activity/index.php?mode=mine", $langs->trans("MyActivities"), 0, $user->rights->projet->lire); - $newmenu->add("/projet/tasks.php?action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); - $newmenu->add("/projet/tasks/list.php?mode=mine", $langs->trans("List"), 1, $user->rights->projet->lire); - $newmenu->add("/projet/activity/perweek.php?mode=mine", $langs->trans("NewTimeSpent"), 1, $user->rights->projet->creer); + $newmenu->add("/projet/activity/index.php?leftmenu=mytasks&mode=mine", $langs->trans("MyActivities"), 0, $user->rights->projet->lire); + $newmenu->add("/projet/tasks.php?leftmenu=mytasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); + $newmenu->add("/projet/tasks/list.php?leftmenu=mytasks&mode=mine", $langs->trans("List"), 1, $user->rights->projet->lire); + $newmenu->add("/projet/activity/perweek.php?leftmenu=mytasks&mode=mine", $langs->trans("NewTimeSpent"), 1, $user->rights->projet->creer); // All project i have permission on $newmenu->add("/projet/activity/index.php", $langs->trans("Activities"), 0, $user->rights->projet->lire && $user->rights->projet->lire); @@ -1452,15 +1453,33 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } } - // For external modules - $tmp=explode('?',$menu_array[$i]['url'],2); - $url = $tmp[0]; - $param = (isset($tmp[1])?$tmp[1]:''); - $url = dol_buildpath($url,1).($param?'?'.$param:''); + $url = $shorturl = $menu_array[$i]['url']; + + if (! preg_match("/^(http:\/\/|https:\/\/)/i",$menu_array[$i]['url'])) + { + $tmp=explode('?',$menu_array[$i]['url'],2); + $url = $shorturl = $tmp[0]; + $param = (isset($tmp[1])?$tmp[1]:''); // params in url of the menu link + // Complete param to force leftmenu to '' to closed opend menu when we click on a link with no leftmenu defined. + if ((! preg_match('/mainmenu/i',$param)) && (! preg_match('/leftmenu/i',$param)) && ! empty($menu_array[$i]['mainmenu'])) + { + $param.=($param?'&':'').'mainmenu='.$menu_array[$i]['mainmenu'].'&leftmenu='; + } + if ((! preg_match('/mainmenu/i',$param)) && (! preg_match('/leftmenu/i',$param)) && empty($menu_array[$i]['mainmenu'])) + { + $param.=($param?'&':'').'leftmenu='; + } + //$url.="idmenu=".$menu_array[$i]['rowid']; // Already done by menuLoad + $url = dol_buildpath($url,1).($param?'?'.$param:''); + $shorturl = $shorturl.($param?'?'.$param:''); + } + $url=preg_replace('/__LOGIN__/',$user->login,$url); + $shorturl=preg_replace('/__LOGIN__/',$user->login,$shorturl); $url=preg_replace('/__USERID__/',$user->id,$url); - + $shorturl=preg_replace('/__USERID__/',$user->id,$shorturl); + print ''."\n"; // Menu niveau 0 diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 8dc599441e2..c8bae6140c1 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -694,17 +694,17 @@ function setforpredef() { jQuery("#prod_entry_mode_free").prop('checked',false); jQuery("#prod_entry_mode_predef").prop('checked',true); jQuery("#price_ht").hide(); - jQuery("#title_up_ht").hide(); jQuery("#price_ttc").hide(); // May no exists jQuery("#tva_tx").hide(); jQuery("#buying_price").show(); + //jQuery("#fournprice_predef").show(); // management somewhere else jQuery("#title_vat").hide(); + jQuery("#title_up_ht").hide(); jQuery("#title_up_ttc").hide(); jQuery("#np_marginRate").hide(); // May no exists jQuery("#np_markRate").hide(); // May no exists jQuery(".np_marginRate").hide(); // May no exists jQuery(".np_markRate").hide(); // May no exists - jQuery(".np_markRate").hide(); // May no exists jQuery("#units, #title_units").hide(); } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 643ad6995a9..814b517ed38 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1549,7 +1549,8 @@ class Expedition extends CommonObject dol_syslog(get_class($this)."::initAsSpecimen"); - // Charge tableau des produits prodids + // Load array of products prodids + $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index f046b4ea61f..e177312a7d6 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1432,7 +1432,7 @@ else { $num = $db->num_rows($resql); $i = 0; $total = 0; - print ''; + print '
'; print ''; print ''; print ''; diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php index 3bf2f87c3b1..496092b7f73 100644 --- a/htdocs/exports/class/export.class.php +++ b/htdocs/exports/class/export.class.php @@ -241,7 +241,7 @@ class Export // Loop on each condition to add foreach ($array_filterValue as $key => $value) { - if (preg_match('/group_concat/', $key)) continue; + if (preg_match('/GROUP_CONCAT/i', $key)) continue; if ($value != '') $sqlWhere.=" and ".$this->build_filterQuery($this->array_export_TypeFields[$indice][$key], $key, $array_filterValue[$key]); } $sql.=$sqlWhere; @@ -256,7 +256,7 @@ class Export // Loop on each condition to add foreach ($array_filterValue as $key => $value) { - if (preg_match('/group_concat/', $key) and $value != '') $sql.=" HAVING ".$this->build_filterQuery($this->array_export_TypeFields[$indice][$key], $key, $array_filterValue[$key]); + if (preg_match('/GROUP_CONCAT/i', $key) and $value != '') $sql.=" HAVING ".$this->build_filterQuery($this->array_export_TypeFields[$indice][$key], $key, $array_filterValue[$key]); } } diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 69932f0c232..8c1a86b03a5 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1647,7 +1647,8 @@ class FactureFournisseur extends CommonInvoice $now = dol_now(); - // Charge tableau des produits prodids + // Load array of products prodids + $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index e9a67a0e98e..34a11663e2a 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -6,8 +6,6 @@ * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2015 Marcos García * Copyright (C) 2016 Charlie Benke - - status * * 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 diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php index 64f6aa4dff0..33c3e268565 100644 --- a/htdocs/fourn/commande/orderstoinvoice.php +++ b/htdocs/fourn/commande/orderstoinvoice.php @@ -71,11 +71,12 @@ $date_end = dol_mktime(23, 59, 59, $_REQUEST["date_endmonth"], $_REQUEST["date_e $date_starty = dol_mktime(0, 0, 0, $_REQUEST["date_start_delymonth"], $_REQUEST["date_start_delyday"], $_REQUEST["date_start_delyyear"]); // Date for local PHP server $date_endy = dol_mktime(23, 59, 59, $_REQUEST["date_end_delymonth"], $_REQUEST["date_end_delyday"], $_REQUEST["date_end_delyyear"]); -if ($action == 'create') { - if (is_array($selected) == false) { - $mesgs = array ( - '
' . $langs->trans('Error_OrderNotChecked') . '
' - ); +if ($action == 'create') +{ + if (! is_array($selected)) + { + $error++; + setEventMessages($langs->trans('Error_OrderNotChecked'), null, 'errors'); } else { $origin = GETPOST('origin'); $originid = GETPOST('originid'); @@ -87,11 +88,12 @@ include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; $hookmanager = new HookManager($db); $hookmanager->initHooks(array('orderstoinvoicesupplier')); + /* * Actions */ -if (($action == 'create' || $action == 'add') && empty($mesgs)) { +if (($action == 'create' || $action == 'add') && ! $error) { require_once DOL_DOCUMENT_ROOT . '/core/lib/fourn.lib.php'; if (! empty($conf->projet->enabled)) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index d14a43764d7..d0edbd1f458 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1736,7 +1736,7 @@ else { $num = $db->num_rows($result); $i = 0; $totalpaye = 0; - print '
'.$langs->trans("RefPayment").''.$langs->trans("Date").'
'; + print '
'; print ''; print ''; print ''; diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index 70f1f3422ea..a07dbc48168 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -853,24 +853,30 @@ function write_conf_file($conffile) fputs($fp,"\n"); /* Authentication */ + fputs($fp, '// Authentication settings'); + fputs($fp,"\n"); + fputs($fp, '$dolibarr_main_authentication=\'dolibarr\';'); fputs($fp,"\n\n"); - fputs($fp, '// Specific settings'); + fputs($fp, '//$dolibarr_main_demo=\'autologin,autopass\';'); fputs($fp,"\n"); - fputs($fp, '//$dolibarr_main_demo=\'autologin,autopass\';'); + fputs($fp, '// Security settings'); fputs($fp,"\n"); fputs($fp, '$dolibarr_main_prod=\'0\';'); fputs($fp,"\n"); - fputs($fp, '$dolibarr_nocsrfcheck=\'0\';'); - fputs($fp,"\n"); - fputs($fp, '$dolibarr_main_force_https=\''.$main_force_https.'\';'); fputs($fp,"\n"); + fputs($fp, '$dolibarr_main_restrict_os_commands=\'mysqldump, mysql, pg_dump, pgrestore\';'); + fputs($fp,"\n"); + + fputs($fp, '$dolibarr_nocsrfcheck=\'0\';'); + fputs($fp,"\n"); + fputs($fp, '$dolibarr_main_cookie_cryptkey=\''.$key.'\';'); fputs($fp,"\n"); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index d7936f43c32..df340688a67 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -512,6 +512,8 @@ Module5000Name=Multi-company Module5000Desc=Allows you to manage multiple companies Module6000Name=Workflow Module6000Desc=Workflow management +Module10000Name=Websites +Module10000Desc=Create public websites with a WYSIWG editor. Just setup your web server to point to the dedicated directory to have it online on the Internet. Module20000Name=Leave Requests management Module20000Desc=Declare and follow employees leaves requests Module39000Name=Product lot @@ -1589,3 +1591,4 @@ DetectionNotPossible=Detection not possible UrlToGetKeyToUseAPIs=Url to get token to use API (once token has been received it is saved on database user table and will be checked on each future access) ListOfAvailableAPIs=List of available APIs activateModuleDependNotSatisfied=Module "%s" depends on module "%s" that is missing, so module "%1$s" may not work correclty. Please install module "%2$s" or disable module "%1$s" if you want to be safe from any surprise +CommandIsNotInsideAllowedCommands=The command you try to run is not inside list of allowed commands defined into parameter $dolibarr_main_restrict_os_commands into conf.php file. \ No newline at end of file diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 01e57a756b9..af2f6174315 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -323,6 +323,7 @@ NextDateToExecution=Date for next invoice generation DateLastGeneration=Date of latest generation MaxPeriodNumber=Max nb of invoice generation NbOfGenerationDone=Nb of invoice generation already done +MaxGenerationReached=Maximum nb of generations reached InvoiceAutoValidate=Validate invoices automatically GeneratedFromRecurringInvoice=Generated from template recurring invoice %s DateIsNotEnough=Date not reached yet diff --git a/htdocs/langs/en_US/printing.lang b/htdocs/langs/en_US/printing.lang index 14577a126e4..2da614e96f9 100644 --- a/htdocs/langs/en_US/printing.lang +++ b/htdocs/langs/en_US/printing.lang @@ -51,3 +51,5 @@ IPP_Supported=Type of media DirectPrintingJobsDesc=This page lists printing jobs found for available printers. GoogleAuthNotConfigured=Google OAuth setup not done. Enable module OAuth and set a Google ID/Secret. GoogleAuthConfigured=Google OAuth credentials found into setup of module OAuth. +PrintingDriverDescprintgcp=Configuration variables for printing driver Google Cloud Print. +PrintTestDescprintgcp=List of Printers for Google Cloud Print. diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index a6f2ba51f23..b1b8d601430 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -83,7 +83,7 @@ SetDefaultBarcodeType=Set barcode type BarcodeValue=Barcode value NoteNotVisibleOnBill=Note (not visible on invoices, proposals...) ServiceLimitedDuration=If product is a service with limited duration: -MultiPricesAbility=Several level of prices per product/service +MultiPricesAbility=Several segment of prices per product/service (each customer is in one segment) MultiPricesNumPrices=Number of prices AssociatedProductsAbility=Activate the package feature AssociatedProducts=Package product @@ -174,13 +174,13 @@ AlwaysUseNewPrice=Always use current price of product/service AlwaysUseFixedPrice=Use the fixed price PriceByQuantity=Different prices by quantity PriceByQuantityRange=Quantity range -MultipriceRules=Price level rules -UseMultipriceRules=Use price level rules (defined into product module setup) to autocalculate prices of all other level according to first level +MultipriceRules=Price segment rules +UseMultipriceRules=Use price segment rules (defined into product module setup) to autocalculate prices of all other segment according to first segment PercentVariationOver=%% variation over %s PercentDiscountOver=%% discount over %s ### composition fabrication Build=Produce -ProductsMultiPrice=Products and prices for each price level +ProductsMultiPrice=Products and prices for each price segment ProductsOrServiceMultiPrice=Customer prices (of products or services, multi-prices) ProductSellByQuarterHT=Products turnover quarterly before tax ServiceSellByQuarterHT=Services turnover quarterly before tax @@ -201,9 +201,9 @@ DefinitionOfBarCodeForThirdpartyNotComplete=Definition of type or value of bar c BarCodeDataForProduct=Barcode information of product %s : BarCodeDataForThirdparty=Barcode information of thirdparty %s : ResetBarcodeForAllRecords=Define barcode value for all records (this will also reset barcode value already defined with new values) -PriceByCustomer=Different price for each customer -PriceCatalogue=Unique price per product/service -PricingRule=Rules for customer prices +PriceByCustomer=Different prices for each customer +PriceCatalogue=A single sell price per product/service +PricingRule=Rules for sell prices AddCustomerPrice=Add price by customer ForceUpdateChildPriceSoc=Set same price on customer subsidiaries PriceByCustomerLog=Log of previous customer prices diff --git a/htdocs/livraison/class/livraison.class.php b/htdocs/livraison/class/livraison.class.php index f77239535a6..45e86b50686 100644 --- a/htdocs/livraison/class/livraison.class.php +++ b/htdocs/livraison/class/livraison.class.php @@ -833,7 +833,8 @@ class Livraison extends CommonObject $now=dol_now(); - // Charge tableau des produits prodids + // Load array of products prodids + $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index faac1a20e10..a5addbc705a 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -416,7 +416,7 @@ if ($resql) if (! empty($arrayfields['p.opp_amount']['checked'])) print_liste_field_titre($arrayfields['p.opp_amount']['label'],$_SERVER["PHP_SELF"],'p.opp_amount',"",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['p.fk_opp_status']['checked'])) print_liste_field_titre($arrayfields['p.fk_opp_status']['label'],$_SERVER["PHP_SELF"],'p.fk_opp_status',"",$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['p.opp_percent']['checked'])) print_liste_field_titre($arrayfields['p.opp_percent']['label'],$_SERVER["PHP_SELF"],'p.opp_percent',"",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre($arrayfields['p.budget_amount']['label'],$_SERVER["PHP_SELF"],'p.budget_amount',"",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre($arrayfields['p.budget_amount']['label'],$_SERVER["PHP_SELF"],'p.budget_amount',"",$param,'align="right"',$sortfield,$sortorder); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index fd7f266e159..00efb287dcc 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2186,7 +2186,8 @@ class SupplierProposal extends CommonObject { global $user,$langs,$conf; - // Charge tableau des produits prodids + // Load array of products prodids + $num_prods = 0; $prodids = array(); $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 979c2622ae3..9e9cf97706c 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -4093,7 +4093,7 @@ select { /* display: inline-block; */ /* We can't set this. This disable ability to make */ /* TODO modified by jmobile, replace jmobile with pure css*/ overflow:hidden; - white-space: nowrap; + white-space: nowrap; /* Enabling this make behaviour strange when selecting the empty value if this empty value is '' instead of ' ' */ text-overflow: ellipsis; } .fiche .ui-controlgroup { diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 28b1040f579..032628e4e67 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -54,6 +54,7 @@ $mode = GETPOST('mode','alpha'); $confirm = GETPOST('confirm','alpha'); $subaction = GETPOST('subaction','alpha'); $group = GETPOST("group","int",3); +$cancel = GETPOST('cancel'); // Define value to know what current user can do on users $canadduser=(! empty($user->admin) || $user->rights->user->user->creer); @@ -299,7 +300,8 @@ if (empty($reshook)) { } } - if ($action == 'update' && !$_POST["cancel"]) { + if ($action == 'update' && ! $cancel) + { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; if ($caneditfield) // Case we can edit all field @@ -395,7 +397,7 @@ if (empty($reshook)) { if (!$error) { $ret = $object->update($user); if ($ret < 0) { - $error ++; + $error++; if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { $langs->load("errors"); setEventMessages($langs->trans("ErrorLoginAlreadyExists", $object->login), null, 'errors'); @@ -1440,6 +1442,49 @@ else print ''; } + // Multicompany + // TODO This should be done with hook formObjectOption + if (is_object($mc)) + { + if (! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + print '\n"; + } + } + + if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file->main_authentication) && ! empty($conf->global->MAIN_OPENIDURL_PERUSER)) + { + print ''; + print ''; + print "\n"; + } + + print ''; + print ''; + print "\n"; + + print ''; + print ''; + print "\n"; + + // Other attributes + $parameters=array(); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields); + } + // Company / Contact if (! empty($conf->societe->enabled)) { @@ -1488,49 +1533,6 @@ else print ''."\n"; } - // Multicompany - // TODO This should be done with hook formObjectOption - if (is_object($mc)) - { - if (! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - print '\n"; - } - } - - if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file->main_authentication) && ! empty($conf->global->MAIN_OPENIDURL_PERUSER)) - { - print ''; - print ''; - print "\n"; - } - - print ''; - print ''; - print "\n"; - - print ''; - print ''; - print "\n"; - - // Other attributes - $parameters=array(); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields); - } - print "
'.$langs->trans('Payments').''.$langs->trans('Date').'
'.$langs->trans("Entity").''; + if (empty($object->entity)) + { + print $langs->trans("AllEntities"); + } + else + { + $mc->getInfo($object->entity); + print $mc->label; + } + print "
'.$langs->trans("OpenIDURL").''.$object->openid.'
'.$langs->trans("LastConnexion").''.dol_print_date($object->datelastlogin,"dayhour").'
'.$langs->trans("PreviousConnexion").''.dol_print_date($object->datepreviouslogin,"dayhour").'
'.$langs->trans("Entity").''; - if (empty($object->entity)) - { - print $langs->trans("AllEntities"); - } - else - { - $mc->getInfo($object->entity); - print $mc->label; - } - print "
'.$langs->trans("OpenIDURL").''.$object->openid.'
'.$langs->trans("LastConnexion").''.dol_print_date($object->datelastlogin,"dayhour").'
'.$langs->trans("PreviousConnexion").''.dol_print_date($object->datepreviouslogin,"dayhour").'
\n"; print ''; @@ -2222,7 +2224,7 @@ else print ''; $cate_arbo = $form->select_all_categories( Categorie::TYPE_CONTACT, null, null, null, null, 1 ); $c = new Categorie( $db ); - $cats = $c->containing( $object->id, 'user' ); + $cats = $c->containing($object->id, Categorie::TYPE_USER); foreach ($cats as $cat) { $arrayselected[] = $cat->id; } diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 6a19be4da1e..5b79447736e 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1332,14 +1332,14 @@ class User extends CommonObject // If user is linked to a member, remove old link to this member if ($this->fk_member > 0) { - $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL where fk_member = ".$this->fk_member; - dol_syslog(get_class($this)."::update", LOG_DEBUG); + dol_syslog(get_class($this)."::update remove link with member. We will recreate it later", LOG_DEBUG); + $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL where fk_member = ".$this->fk_member; $resql = $this->db->query($sql); if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; } } // Set link to user + dol_syslog(get_class($this)."::update set link with member", LOG_DEBUG); $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member =".($this->fk_member>0?$this->fk_member:'null')." where rowid = ".$this->id; - dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; } @@ -1347,6 +1347,8 @@ class User extends CommonObject { if ($this->fk_member > 0 && ! $nosyncmember) { + dol_syslog(get_class($this)."::update user is linked with a member. We try to update member too.", LOG_DEBUG); + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; // This user is linked with a member, so we also update members informations @@ -1360,7 +1362,9 @@ class User extends CommonObject $adh->lastname=$this->lastname; $adh->login=$this->login; $adh->gender=$this->gender; + $adh->pass=$this->pass; + $adh->societe=(empty($adh->societe) && $this->societe_id ? $this->societe_id : $adh->societe); $adh->email=$this->email; @@ -1373,17 +1377,19 @@ class User extends CommonObject $adh->user_id=$this->id; $adh->user_login=$this->login; - $result=$adh->update($user,0,1); - if ($result < 0) + $result=$adh->update($user,0,1,0); + if ($result < 0) { - $this->error=$luser->error; - dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR); + $this->error=$adh->error; + $this->errors=$adh->errors; + dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR); $error++; } } else { $this->error=$adh->error; + $this->errors=$adh->errors; $error++; } } @@ -1495,7 +1501,7 @@ class User extends CommonObject $password=getRandomPassword(false); } - // Crypte avec md5 + // Crypt password $password_crypted = dol_hash($password); // Mise a jour @@ -1539,7 +1545,7 @@ class User extends CommonObject if ($result >= 0) { - $result=$adh->setPassword($user,$this->pass,0,1); // Cryptage non gere dans module adherent + $result=$adh->setPassword($user,$this->pass,(empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1),1); // Cryptage non gere dans module adherent if ($result < 0) { $this->error=$adh->error; diff --git a/scripts/product/migrate_picture_path.php b/scripts/product/migrate_picture_path.php index 9d3cba8452f..f8624ebc040 100755 --- a/scripts/product/migrate_picture_path.php +++ b/scripts/product/migrate_picture_path.php @@ -1,6 +1,6 @@ #!/usr/bin/env php +/* Copyright (C) 2007-2016 Laurent Destailleur * Copyright (C) 2015 Jean Heimburger * * This program is free software; you can redistribute it and/or modify @@ -21,7 +21,6 @@ * \file scripts/product/migrate_picture_path.php * \ingroup scripts * \brief Migrate pictures from old system prior to 3.7 to new path for 3.7+ - * */ $sapi_type = php_sapi_name(); @@ -119,7 +118,7 @@ function migrate_product_photospath($product) $handle=opendir($origin_osencoded); if (is_resource($handle)) { - while (($file = readdir($handle)) != false) + while (($file = readdir($handle)) !== false) { if ($file != '.' && $file != '..' && is_dir($origin_osencoded.'/'.$file)) { @@ -127,7 +126,7 @@ function migrate_product_photospath($product) if (is_resource($thumbs)) { dol_mkdir($destin.'/'.$file); - while (($thumb = readdir($thumbs)) != false) + while (($thumb = readdir($thumbs)) !== false) { dol_move($origin.'/'.$file.'/'.$thumb, $destin.'/'.$file.'/'.$thumb); } diff --git a/test/phpunit/CategorieTest.php b/test/phpunit/CategorieTest.php index d9e030ef9ef..574a8d793f9 100644 --- a/test/phpunit/CategorieTest.php +++ b/test/phpunit/CategorieTest.php @@ -200,7 +200,7 @@ class CategorieTest extends PHPUnit_Framework_TestCase // Get list of categories for product $localcateg=new Categorie($this->savdb); - $listofcateg=$localcateg->containing($localobject2->id, 'product', 'label'); + $listofcateg=$localcateg->containing($localobject2->id, Categorie::TYPE_PRODUCT, 'label'); $this->assertTrue(in_array('Specimen Category for product',$listofcateg), 'Categ not found linked to product when it should'); return $id; diff --git a/test/phpunit/PgsqlTest.php b/test/phpunit/PgsqlTest.php index f25ea3ea72f..05efcaeb30b 100644 --- a/test/phpunit/PgsqlTest.php +++ b/test/phpunit/PgsqlTest.php @@ -162,11 +162,17 @@ class PgsqlTest extends PHPUnit_Framework_TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals($result, $sql.' DEFERRABLE INITIALLY IMMEDIATE;'); - // Create a constraint - $sql='SELECT a.b, GROUP_CONCAT(a.c) FROM table GROUP BY a.b'; + // Test GROUP_CONCAT (without SEPARATOR) + $sql="SELECT a.b, GROUP_CONCAT(a.c) FROM table GROUP BY a.b"; $result=DoliDBPgsql::convertSQLFromMysql($sql); print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, "SELECT a.b, STRING_AGG(a.c, ',') FROM table GROUP BY a.b"); + $this->assertEquals($result, "SELECT a.b, STRING_AGG(a.c, ',') FROM table GROUP BY a.b", 'Test GROUP_CONCAT (without SEPARATOR)'); + + // Test GROUP_CONCAT (with SEPARATOR) + $sql="SELECT a.b, GROUP_CONCAT(a.c SEPARATOR ',') FROM table GROUP BY a.b"; + $result=DoliDBPgsql::convertSQLFromMysql($sql); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, "SELECT a.b, STRING_AGG(a.c, ',') FROM table GROUP BY a.b", 'Test GROUP_CONCAT (with SEPARATOR)'); return $result; }